Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Bind to parent datacontext (out of itemsource)

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).

like image 368
devha Avatar asked Apr 22 '14 19:04

devha


People also ask

What is the difference between DataContext and ItemsSource?

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.

What is a DataContext?

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.

What is DataContext WPF?

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.


1 Answers

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.

like image 110
Rohit Vats Avatar answered Sep 21 '22 09:09

Rohit Vats