In my Windows Phone 8 app I have list of items. I have defined ItemTemplate for list items.
I want to display in each of these items one value from view model, not from the list item itself. How should I set up the binding from list item to viewmodel.
My data template is like this:
<DataTemplate x:Key="template">
<StackPanel>
<TextBlock Text="{Binding Name}"/> <!-- From list item -->
<TextBlock Text="{Binding MyViewModel.Country ?? }"/> <!-- From view model -->
</StackPanel>
</DataTemplate>
So how to bind Country property to view model, not list item (in item source).
DataContext does not generate template, it only used to hold common data for other controls to bind. In terms of ItemsSource property, it is mainly used to generate template regardless of you set it in XAML or in the code behind. DataContext is mainly used to hold common data that other child want to share.
Data context is the network of connections among data points. Those connections may be created as metadata or simply identified and correlated. Contextual metadata adds value, essentially making it possible to receive information from data.
The DataContext property is the default source of your bindings, unless you specifically declare another source, like we did in the previous chapter with the ElementName property. It's defined on the FrameworkElement class, which most UI controls, including the WPF Window, inherits from.
Since you tagged your question with WPF
, I can tell you the way of doing it in WPF, you can validate if that can be reused in Windows phone 8 apps.
First, you can give x:Name
to root element to which ViewModel is bind to. Say it's window, set x:Name on it and bind using ElementName
.
<Window x:Name="myWindow">
...
<DataTemplate x:Key="template">
<StackPanel>
<TextBlock Text="{Binding Name}"/> <!-- From list item -->
<TextBlock Text="{Binding DataContext.MyViewModel.Country,
ElementName=myWindow }"/> <!-- From view model -->
</StackPanel>
</DataTemplate>
</Window>
Second, you can try using RelativeSource
to travel Visual tree and get root element DataContext.
<DataTemplate x:Key="template">
<StackPanel>
<TextBlock Text="{Binding Name}"/> <!-- From list item -->
<TextBlock Text="{Binding DataContext.MyViewModel.Country,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=Window} }"/>
<!-- From view model -->
</StackPanel>
</DataTemplate>
Moreove, if ListBox is inheriting DataContext from root element (i.e. you haven't explicitly set DataContext on ListBox). You can use both approaches on ListBox as well in place of Window.
Note - As mentioned here, FindAncestor
is not defined for Windows phone 8 but element name does work. So, try using first approach and it should work for you.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With