I have a TextBox bound to the Entity Framework object User. Works fine. But now, when I change the User object to the new User.CreateUser(0, ...) or null, TextBox doesn't change.
Why?
Best regards, James
pls post your binding and your datacontext, otherwise its hard to say whats wrong. i could just assume that INotifyPropertyChanged is not implemented.
You have to make sure that the binding hooks in at right level, not all changes are observed by the binding engine, e.g. if you only specify the Source that is identical to assigning the object referenced by the source, the binding will look for the PropertyChanged event on the source to update itself if you bind to a property using the Path, however it will never know if the source is swapped out.
If you bind to the User using the path this is not your issue, just what exactly is wrong is not inferable (for me, that is) from your question alone, you should probably post some code.
Related
Right. So moving from WPF to UWP, I'm trying to use x:Bind to get compile-time benefits. Simple scenarios work fine; however I have found a number of issues that I was not able to solve. They are all related, so I thought I'd post them in one place:
I haven't been able to make Intellisense work with x:Bind. I have set DataContext (as well as d:DataContext just as we do in WPF) both in XAML and in the constructor, but it won't show members no matter what. Has anyone done this successfully?
Then I read somewhere that in UWP, DataContext is always set to Page's code-behind (really??) and that I need to define a ViewModel type property in the code-behind and then use that property in x:Bind. Is this correct? I tried it and it works but gives rise to the next question.
If I define a property of ViewModel type in Page's code-behind, Any sub-properties that raise PropertyChanged notifications do not update the UI. For example, if the code-behind property is named Game (of type GameVM) and there is a public property in GameVM named Player (of type GamePlayer), and in turn GamePlayer contains a property named Name, the x:Bind path will look like {x:Bind Path=Game.Player.Name}. But if I do this, any change notifications raised from within Name property do not update Page's UI.
One alternate I tried was to listen to PropertyChanged at each level and then bubble it up the hierarchy, but that hasn't worked. Even if it does, doing this seems a bit too much work. In WPF sub-properties like Game.Player.Name work properly without having to doing property change bubbling. Or am I missing something?
Right. After playing with it for a few days and searching numerous references, here are my findings:
{x:Bind} lacks design-time support. The feature is on the wishlist though. You may want to upvote it there.
(The new version of Visual Studio 15.4.4 does support Intellisense in {x:Bind}in the required way.)
{x:Bind} uses code-behind as its DataContext. So you need to define a public property of your ViewModel type in the code-behind and then use it in your {x:Bind} path.
As pointed out by IInspectable, the default mode for {x:Bind} is OneTime, unlike {Binding} which uses OneWay or TwoWay in almost all cases. So you need to explicitly specify Mode in your binding. People coming from WPF should take special care of it.
Sub-properties that implement notification change work perfectly fine in {x:Bind}. There is no need of bubbling these notifications upwards in the property hierarchy. The problem I was facing (#3 in the question) was because my sub-property was of type List<T>. I changed it to ObservableCollection<T> and it started working.
Hope this works somebody down the road.
Well as a beginner, the only question I can answer for you is the first one. Intellisense does not work inside the {x:Bind}. The members are never shown there in UWP for some unknown reasons. As for the next two questions of yours, I am still working on them.
I ran into the same challenge that you have seen. In my experience, in order to create the compile-time binding and have it update with custom objects as properties, the Page class seems to need to know about the data context and custom objects... all you need to do is reference them in the code behind, and then bind to them in the XAML. This creates the code generation objects it needs.
For example, I have a viewmodel, CustomerViewModel that is bound in XAML. That viewmodel also has a property of type IGuest. In order to use the guest object and have it update properly, I came up with this in the code behind...
CustomerViewModel vm
{
get
{
return (CustomerViewModel)DataContext;
}
}
IGuest g
{
get
{
return vm.CurrentGuest;
}
}
public CartGuestControl()
{
this.InitializeComponent();
}
You don't need to assign any of the UI data contexts from the code behind... simply reference the datacontext that is bound in XAML. When binding to any straight viewmodel properties, I use {x:Bind Path=vm.IsEditing, Mode=OneWay}. For binding to any of the guest properties, it looks like this, {x:Bind Path=g.FirstName, Mode=TwoWay}. You could do something like this for your Player object.
I have run into times where x:Bind simply won't do what I expect it to do no matter what I try. This can usually be solved by breaking things out into smaller user controls with more specific data contexts or by using "regular" Binding.
Well, i must admit, still sometimes XAML seems a bit mysterious to me. The thing is, i always liked to debug through the C# code (setting lots of breakpoints in them) to get the idea of "what is happening" and "how is it happening". But with declarative XAML syntax that's not an option. I think you'll agree that to work with XAML, or to be precise, to work with/understand some existing XAML code you got to "already know" how things work with XAML declaration. There is just no way you can know/learn things investigating the execution of your application code. So i'm more than interested to take a look through XAML inside-out, as detailed as possible. I'm NOT talking about "learning" XAML, I know the basic stuff. May be i can provide some examples to clarify the sort of things i'm looking for -
Compared to C# code how an object gets instantiated when we use them in XMAL? Are they stored in managed heap? Same way as C# code-instantiated objects?
How the properties get set while using Mark-Up Extension syntax for Data/Command Binding?
When any property of an INotifyPropertyChanged type gets updated, how the Binding instatnce inside the XAML syntax updates the itself? How exactly it gets notified it at the first place, & by whom?
A viewmodel can be set as the DataContext of a view at runtime by defining Typed DataTemplate, like -
<DataTemplate DataType="{x:Type viewmodels:AccountsViewModel}">
<views:Accounts/>
</DataTemplate>
How does it happen actually? What are the rules for setting DataContext other than searching for the DataContext property upward the logical tree?
How the whole template things (DataTemplate, ControlTemplate & ItemsPanelTemplate) are treated/resolved at run time.
etc. etc. etc.
So if you are good/experienced/expert in XAML what would you suggest (links, articles, blogposts, books whatever) as reference that helps getting clear & deeper understanding about how XAML works "under-the-hood"? Thanks in advance.
Most can be explained by don't thinking of XAML as a real programming language, more like a declarative language. Everything you do in xaml, can be made in C# aswell, and in fact this is whats happening.
Compared to C# code how an object gets instantiated when we use them
in XMAL? Are they stored in managed heap? Same way as C#
code-instantiated objects?
Yes because they are just c# objects. Most resources are stored in a hibernated state, i rememberd the word inflated somewhere. Converter or other "direct" c# objects are created when they are needed. Important here is that these resources are usually shared, so they will get created only once.
How the properties get set while using Mark-Up Extension syntax for Data/Command Binding?
This again depends on where you use the markup extension. In a Style? In a Template? In a instanced user control like a window? Usually they are evaluated when you actually need them. It wouldn't make sense to evaluate them, when the inflated style is stored in the actual resource dictionary. They get evaluated when you actually use the style on an object.
When any property of an INotifyPropertyChanged type gets updated, how
the Binding instatnce inside the XAML syntax updates the itself? How
exactly it gets notified it at the first place, & by whom?
By the binding engine. WPF checks if your DataContext inherits the INotifyPropertyChanged interface, attaches to the event provided by the interface and listens to any changes. If such an event is raised, the binding engine will just call the getter again.
How does it happen actually? What are the rules for setting DataContext
other than searching for the DataContext property upward
the logical tree?
In short: None other. Datacontext is simply an inherited attached property. If you don't re set it on a child control, it will take the value the parent has until it reached the root. The only exception to this are ContentControls and ContentPresenter they will not inherit the DataContext but will change them depending on the content. So these controls always have by default the Content as their DataContext.
How the whole template things (DataTemplate, ControlTemplate & ItemsPanelTemplate) are treated/resolved at run time.
Simply spoken: Everytime WPF finds a non ui object, it tries to find a DataTemplate for the given type. In an ItemsControl for example: You can bind a list of MyClass; unless you provide an explicit DataTemplate or DataTemplateSelector it will search the resource tree upwards for an implicit style. Again remember that this already does not happen in XAML, but on the C# objects that was generated out of the xaml.
And is it by any means possible (at present or near future) to debug
through XAML code?
How do you think you can debug something that is not executed, but evaluated on compile time?
Please don't take this as 100% correct. Over the Years this is what i gathered of informations about XAML and the usage. If you have any corrections or find something that is clearly wrong. Please tell me, we are all here to learn and i always learn new things about the stuff i use :)
I'm a bit stuck on this one. Clearing the binding of the TextProperty of some TextBox that is not part of a DataTemplate works fine. But when the TextBox is part of a DataTemplate, clearing the binding seems to be a no-op as shown in the snip below. The watch value is true even after the binding is presumably cleared:
Is this by design? If not, what am I doing wrong?
Here is the MSDN documentation of ClearBinding(...): http://msdn.microsoft.com/en-us/library/system.windows.data.bindingoperations.clearbinding
I found this MSDN post that covers the issue. While it seems to leave the issue without a real explanation, it does provide a workaround that seems to work just fine.
I replace the ClearBinding invocation with replacing the binding with some dummy value:
AssociatedObject.SetBinding(TextBox.TextProperty, "dummy");
Now it seems that this will break when the control is not from a DataTemplate. So to work-around that, and so cover TextBoxes from DataTemplate and otherwise, I now do this:
BindingOperations.ClearBinding(AssociatedObject, TextBox.TextProperty);
if (BindingOperations.IsDataBound(AssociatedObject, TextBox.TextProperty))
AssociatedObject.SetBinding(TextBox.TextProperty, "dummy");
And voila, the binding is "severed" and so my watermark seems to work just fine now.
Not sure if this would work (didn't try), but please try using BindingOperations.ClearAllBindings() method as stated in this excerpt from MSDN (see below how MSDN refers to Data Template):
Clearing the binding removes the binding so that the value of the
dependency property is changed to whatever it would have been without
the binding. This value could be a default value, an inherited value,
or a value from a data template binding.
To clear bindings from all possible properties on an object, use
ClearAllBindings.
I've got a strange problem - binding created through XAML (both ways by markup extension or normal) isn't working(BindingOperations.IsDataBound returns false and in fact there is no Binding object created). When I do literally the same from code everything is working perfectly.
One more thing is that the Binding in XAML is created in a DataTemplate - what's funny about that when I use the DataTemplate for the first time it fails, then I fix it from code (add binding to specific objects) and while adding more objects to the collection the binding set in XAML just works. If I try to remove all the objects from the collection and then add a new one the binding fails once again.
In reality this is a shortened version of another of my questions. For details please refer to:
WPF Debugging AvalonEdit binding to Document property
Sorry for doing it this way, but there's no answer and it's probably too long for anybody to read.
-
Is there any exception traced in Output window? WPF usually complains there instead of just failing the program.
The problem may be related to your use of IsAsync and some problem with the target property's handling of an invalid result. You might want to try getting rid of the IsAsync parameter or using a PriorityBinding to set a safer default to use while waiting for the async loading to complete.
I'm trying to add some extra logging to my C# winforms application. I have a few data bound forms that all the database stuff is managed by a binding source and some typed datasets/adapters.
With this setup, it's kind of difficult to tell when something is changed, I'd have to manage each field and keep it's previous value. Is there a way I can hook into the dataset and tell when something is changed? I know datarow's have a RowState enumeration, would that be a good place to start? I looked into the binding source's DataMemberChanged event but it never fired so...
To get the original value of an updated Data value you can do this:
<DataTableRow>[<DataColumn>, DataRowVersion.Original]
To know what has changed look at the DataSet.GetChanges method. The example shows how to get the changes and go through them. I also have an old example here that uses a DataTable and shows how to do a comparison after a merge. It inspects the RowState and shows the changed values etc. It's near the bottom of the page and it's in VB since the OP was using that, not C#. I'm headed out now so I can't provide an equivalent translation but it should be pretty straightforward to glean some useful techniques from.
You can use the RowChanged event, the RowChanging event, or any of the other events raised by a DataTable.