MvxFullBinding not updating on MainThread - xamarin.android

With MvvmCross 3.5.1, I've found that when using MvxFullBinding in the android layout binding description, the UpdateTargetFromSource method is not called on the MainThread.
Is this on purpose? I was thinking that it will behave the same as on RaisePropertyChanged.
Given a full binding like this:
<TextView
style="#style/ValueText"
local:MvxBind="Text SelectedObject.Name" />
And the view model containing the selected object:
public IMyObject SelectedObject { get; }
Where the selected object implements the INotifyPropertyChanged.
If the Name property change is notified from another thread in the application, the update will not be effective and MainThread exception will be thrown : android.view.ViewRootImpl$CalledFromWrongThreadException: Only the original thread that created a view hierarchy can touch its views.
Thanks for the help, and Long Life to MvvmCross :-)

It's the job of the INotifyPropertyChanged implementation to put notifications onto the UI thread
The MvxViewModel and MvxNotifyPropertyChanged classes do this automatically for you - but if you implement your own INotifyPropertyChanged classes, then you'll need to make sure PropertyChanged is raised on the UI thread.

Related

Forcing UnityContainer to create instance on specific thread

I want to find a way to make my UnityContainer create instances that inherit from DispatcherObject on the UI thread. Basically this is what I want:
if (objectType is DispatcherObject)
{
Application.Current.Dispatcher.Invoke(
// DO BUILDUP HERE
);
}
else
{
// DO BUILDUP HERE
}
Looking at the Unity source code I can't find a good way to do this. My best option so far is to register a static factory for every instance I want to push to the UI thread but I would like all DispatcherObject derived classes to be created on the UI thread.

Load object into another class's List XNA C#

Say you have a ScreenManager which inherits DrawableGameComponent, and a GamePlayScreen which inherits GameScreen. And GamePlayScreen is drawn through ScreenManagers ContentManager, and functions just like Game1.cs would. And its LoadContent looks like:
public override void LoadContent()
if (content == null)
content = new ContentManager(ScreenManager.Game.Services, "Content")
foreach (Objects object in objects)
object.LoadContent();
And object class calls same LoadContent method, but of course says object = content.Load<Texture2D>(" - ");... I'm getting the error:
"content = new ContentManager(ScreenManager.Game.Services, "Content") - Object reference not set to an instance of an object." In my objects class LoadContent method.
Is there a way to call GamePlayScreen's content or ContentManager, from the object class?
+++++++++++++++++++++++
Ok, I've realized what exactly the problem is. I'm using the Logic of the GameStateManagement Sample, "created by the head tech of Xbox Indie Games", which is in its own right is brilliant code... If all you're doing is making a main menu... lol...
BUT, ScreenManager is the DrawableGameComponent, its list of GameScreen's makes it and said screen the only functioning things in the Game. Or possibly only the screens are, and when they transition off ScreenManager is called, wakes up, adds new screen and goes to sleep again.
Thus NOT allowing you to call any classes, object list's, or anything contained in another class...
Now one may think, just create a new ScreenManager2 : DrawableGameComponent , or maybe even an ObjectManager : DrawableGameComponent .... Ahh ahhh, already beat you to it friend.....
Creating a new ObjectManager allows your objects to be drawn over everything your original ScreenManager deals with... True;... including your PauseScreen, and PauseMenu.... Garbage!
And before you mention a ScreenManager2, that to handle PauseScreen and PauseMenu, tried that as well. I successfully manipulated all code to do so, up until Play was selected for ScreenManager to tell LoadingScreen to function, then call GamePlayScreen...
Which leads to Asik being right, my content is Null, because I cannot figure out a way for my object class/classes to be called and Initialized with the way this code works.
Which leads to me asking the question correctly...
How do you call a class to Initialize, just long enough to allow LoadContent in the GamePlayScreen to gather said classes/objects information, to be put in its object list?
Lehman's terms: "GamePlayScreen on your LoadContent function, wake up Object1.cs, add object information in your ObjectList, tell Object1.cs to sleep, GamePlayScreen go on with your bad self..." ???
You are making use of GameComponent and DrawableGameComponent. Your subclasses that inherit from these have access to the Game instance via their GameComponent.Game property (that is, if you've passed it into their constructors rather than specifying null.
This is good. Just use GameComponent.Game.Content to access the ContentManager in each.
"Object reference not set to an instance of an object" is a NullReferenceException: it means you're trying to access something from a variable that is currently null. On the line you have posted, I see two possibilities: either ScreenManager.Game is null, or ScreenManager.Game.Services is null. Why? Because you're not initializing them by the time this line gets called.
That said, why not just pass the ContentManager that whatever class needs it rather than instantiate new ones?
With the complexity of ScreenManager, I found no way to load the content directly from the Object1 class, I was however able to call an older form of object handling:
In Object1 class...
Texture2D image;
public Object1(Texture2D texture)
{
this.image = texture;
//other information...
}
Even though SpriteBatch was never declared in the objects class, I was able to call:
public override void Draw(SpriteBatch spriteBatch)
{
spriteBatch.Draw(image, Rectangle, Color.White);
}
And in GamePlayScreen's LoadContent:
Texture2D tempImage = content.Load...
objectList.Add(new Object1(tempImage));
And then in GamePlayScreen's Draw function which calls for GameTime, I called:
foreach (Objects object in objectList)
object.Draw(spriteBatch);
After 2 weeks later, this is finally resolved... And I quote myself:
"It all looks so easy, until you're the one who needs to figure it out..."

iOS: Pattern for mapping view inputs to NSManagedObject

I am building an app with a view controller that represents a form for creating and editing a Task object. It has the following behaviour:
On initialization of the controller, a Task object (NSManagedObject subclass) is initialized in the MOC
NSNotificationCenter observers are set up for each input in the view.
When an input's value is changed, the corresponding property of the Task object is updated via the observers' assigned method. (eg. - (void)taskNameChanged;)
When the user taps Save, the Task object is committed to the data store. If the user taps cancel, the Task object is discarded from the MOC.
I have a feeling that there is a better way to do this. What is the most common pattern for this type of transaction?
It's uncommon to use notifications in cases like this. The question you need to ask is: Do you need to update it all the time? Most of the times you won't. I usually just the values when the Save button is tapped.
In case you would have to check the values earlier, you still don't want to use notifications. I usually go for hooking up a IBAction to one of the events in Interface Builder. Another option is using the delegate, in that case your UIViewController instance would implement the UITextFieldDelegate protocol.
Unfortunately, iOS lacks Cocoa Bindings, so you end up having to implement a light version yourself.
I did this for our app, and it ended up working well. I used KVO instead of notifications, for two-way binding. I created a dictionary mapping between the object properties and UI elements, and using KVC set up the binding when the view is loaded. In my implementation, I added an option to hint which value should take precedence (this is less valuable for data<->UI, but I wanted something more generic). Eventually, I added support for block-based data transformation between binded objects, so that UI could present text, while the data backing object could hold different types of data.
Please note that UIKit is not KVO compliant. I created KVO-compliant versions of UITextField and UITextView, by listening to notifications and sending the appropriate KVO messages.
While, I cannot post code of this, I hope this gives you ideas regarding your further adventures.

How to improve performance on loading

I have method getStudents on managed BackBean, I am calling getstudents which inturn makes a call to database and fetches the data. The UI shows properly, but its causing performance issue as it takes too much time to load the page . Please suggest me how to handle this performance issue.
You should no do business logic in getter methods. You should init your list in #PostConstruct method or do lazy loading in getter:
private List myList;
#PostConstruct
public void init() {
// init my List
}
// getter and setter
#PostConstruct method will be called after managed bean instantiation. I suggest you to init in this method, not in constructor. As you are changing your list during the backing bean life, you should update it when it is changed. You can add data which was created by user, or you can chose to call database again after inserting values. You have to worry about this, there is no automation.

call delegate method if property changes

I use RestKit with Object-mapping. This runs asyncronus and after receiving the Data from Server an object is updated.
The point is, i need to inform another class that a property of an object has changed.
Right now i run into an error:
bool _WebTryThreadLock(bool), 0x1ae420: Tried to obtain the web
lock from a thread other than the main thread or the web thread.
This may be a result of calling to UIKit from a secondary thread. Crashing now...
I tried to overwrite the setter for the property, but it looks like the property is set in another thread, not the main thread. calling a delegate there does not work.
What can i do to solve this?
Any help is appreciated!
Maybe you need send message like this:
[obj performSelectorOnMainThread:#selector(method)]

Resources