How does the binding work in WPF/XAML? - wpf

How does the binding work in xaml when we mention a property name even if the property doesn't exist, the code doesn't break, how and why is that?

WPF swallows binding exceptions. If you run with the debugger attached and look at your output window, you will see error messages being traced for binding failures.

Related

Prism app shuts down when exception during region creation

We have an application that throws an UpdateRegionsException while launching. We suspect it has to do with a DataContext not being set properly in our XAML. Has anyone come across this type of problem before?
It seems as though there's a bug with elements such as Checkbox, and DatePicker, and perhaps others. On some cases I'm forced to put the DataContext prefix to my property name. For example,
IsEnabled="{Binding DataContext.TransferOriginalRxInformationNeverFilled, Converter={StaticResource InvertBooleanConverter}}"
If I don't put the DataContext prefix to the binding, the application shuts down during startup giving the following exception:
Microsoft.Practices.Prism.Regions.UpdateRegionsException: An exception occurred while trying to create region objects.
Hope this helps anyone in the future.

ListBox.DisplayMemberPath doesn't work as expected. How can I debug this?

<ListBox ItemsSource="{Binding Path=Commands}" DisplayMemberPath="Name"/>
DisplayMemberPath doesn't work, and ListBox shows default ToString result of the Commands collection members. Is it possible to debug this, for example, by printing some information to Output window?
Visual Studio 2010, WPF application project. Binding is successful, and I see all members of the Commandscollection. But display is wrong.
Additional information. If I change Path=Commands to non-existing Path=Commands1, I see error messages in the Output window. But there is no any information about error in DisplayMemberPath.
One of the clearer/cleaner ways I've come across for debugging binding errors in WPF is often linked (but using an older, broken link) and can currently be found here: http://www.zagstudio.com/blog/486#.UhyT8fNwbs0
Specifically, the approach that uses a debugging feature introduced in .Net 3.5, using the attached property PresentationTraceSources.TraceLevel and allows you to specify a particular trace level to investigate your binding issues.
Summarising here:
You add the following namespace:
<Window
<!-- Window Code -->
xmlns:diagnostics="clr-namespace:System.Diagnostics;assembly=WindowsBase"
/>
And in your binding expression, set the attached property. In my example, I'm using a list of Cars objects with a Name property, and have incorrectly listed the DisplayMemberPath as Names:
<ListBox ItemsSource="{Binding Path=Cars, diagnostics:PresentationTraceSources.TraceLevel=High}" DisplayMemberPath="Names" />
This results in the following message in the Output window (occurring multiple times, one for each failed binding):
System.Windows.Data Error: 40 : BindingExpression path error: 'Names' property not found on 'object' ''Car' (HashCode=59988153)'. BindingExpression:Path=Names; DataItem='Car' (HashCode=59988153); target element is 'TextBlock' (Name=''); target property is 'Text' (type 'String')
The whole link is worth a read, but that's the gist of a particular technique I had success with (in case the link dies).
DisplayMemberPath does work... are you sure that you're using it correctly? You can find an example of it on the ItemsControl.DisplayMemberPath Property page at MSDN. For your example code to work, you would need to have a public Name property on the data type in the Commands object.
Failing that, WPF errors generally get output into the Visual Studio Output window. If you do not see any errors there, check that you have the options set correctly:
Go to Tools > Options > Debugging tab > Output Window > WPF Trace Settings
You should have at least one of these options (like Data Binding) set to either Warning, Error, All, Critical or Verbose to receive error information.
if you want to use Property "Name" of your "Commands" Item, plese use the following
<ListBox ItemsSource="{Binding Path=Commands}" SelectedItem="{Binding SelectedCommandsItem, Mode=TwoWay}" DisplayMemberPath="Name"/>
Where SelectedCommandsItem is a property of your model that strictly defines a type of the collection items

Binding in mapping converter

I try to use MappingConverter (existed in our appication and worked nice) in this way:
<converters:MappingConverter x:Key="RewardTypeToSymbolConverter"
ElseMappingValue="BlaBla">
<converters:MappingEntry FromValue="{x:Static loc:SomeEnum.Value}"
ToValue="{Binding SomeStringInViewModel}" />
</converters:MappingConverter>
I get no exceptions, but my TextBlock show nothing. Breakpoint within a converter shows that ToValue property is NULL (but SomeStringInViewModel isn't).
Do anybody have some idea how can I use binding like this within a converter? Or using binding in resource is impossible?
Because Converters aren't in any tree, the DataBinding of the ToValue will not work.
Have look at Josh Smiths DataContext-Bridge-Pattern.
Converters are not in any tree, be it logical or visual. There should be no DataContext at all, if you want to do any kind of binding there you should specify a source (RelativeSource will of course not work) in addition to the path.
In any case, have a look at the output window of Visual Studio, the binding errors displayed there often help find the problem. Also see this article on debugging bindings.
It sounds like your DataContext is incorrect
I would recommend using a tool like Snoop to figure out what your DataContext is

How to confirm what properties are being bound to in XAML?

I've got a "MainModelView" which implements INotifyPropertyChanged and has a property that exposes an ObservableCollection<T> called ExposedCollection. In our MainPage.xaml, we have a ListBox whose ItemsSource is supposed to be bound to MainModelView.ExposedCollection.
The MainModelView makes a REST call to populate the ExposedCollection in the background. When WebClient is done doing its thing, the ASyncCallback calls NotifyPropertyCHanged which checks if the PropertyChanged event is null, and if not raises it. Pretty basic stuff
Problem is, ListBox never seems to bind to ExposedCollection. I set a breakpoint on our null check for NotifyPropertyChanged, and there are never any listeners on PropertyChanged.
I've tried instantiating MainViewModel in PhoneApplicationPage.Resources, in PhoneApplicationPage.DataContext and the PhoneApplicationFrame.DataContext in App.xaml. In all cases the PropertyChanged event is still null. What am I missing here?
<phone:PhoneApplicationPage.DataContext>
<gmvm:MainViewModel x:Name="MainViewModel" />
</phone:PhoneApplicationPage.DataContext>
...
<ListBox x:Name="MyListBox" ItemsSource="{Binding ExposedCollection}" Margin="0,20,-12,0">
.....
</Listbox>
You should check the Output window in Visual Studio to see if there are any binding errors when running your app.
I'm not sure if it makes a difference, but have you tried implementing ExposedCollection as a Dependency Property? If you do that, it might eliminate the need for implementing the INotifyPropertyChanged interface and help with the binding to the listbox?
Crazier things have worked for me...

DataBinding happens only first time

I have two User Controls in my window, both are bound to the same context.
One of them is getting updated and the other is not.
What could be the reason?
Sounds like you have an issue with the bindings. Make sure your dependency properties bound to each control are both getting notified via OnPropertyChanged. If both properties aren't getting notified this would be your issue regardless if they share the same datacontext (viewmodel).
Blessings,
Jeff
Beware of UserControls by default they bind one way you have to specify TwoWay:
<Binding Mode="TwoWay" ...>
...
</Binding>
Do you see any binding errors in the Output window? If so you can post that and maybe we can understand.
If not try to put a dummy converter in the binding and see if its methods are hit.
One from the multiple issues could be binding source address is changed.
Without seeing the code, we only guess:
Check that the property names in the bindings are an exact match (including case). It is quite common to have typing errors that cause bindings to fail (silently).

Resources