views:

65

answers:

2

Hi My main question is about binding case in the scene that we have multiple sources for a control(a combobox inside a datagrid)(or having both datacontext and itemssource). Then how can we know which source the binding will use? (any syntax to clarify that)

Assuming a datagrid has an itemssource="List of Players" datacontext="Manager" , and has a combobox as a kind of column. We also assume that each player has an Inventory property which is a collection type.

then inside the datagrid.columns:

  1. The current source of each column(for binding) is a Player(this is how i understand it so far). We can only bind to the property of the player not to the property of the datacontext "manager". There is no way to bind to the property of the "Manager". Am i correct?
  2. However, if we move to the combobox columns, then assume i will let combobox's itemssource ='player 's inventory', then the current source for comboboxItem will be each item in the inventory. And if i use the binding, it can only bind to the property of those items. However, sometimes i see the code that we can also bind to the property of the player inside the combobox's property especially Selected Value and SelectedItem. I am a little confused here can you help me?

thank you

+1  A: 

The key control to think about is an ItemsControl (ComboBox inherits from ItemsControl and the DataGrid behaves very similar). An ItemsContral has ItemsSource property of type IEnumerable. It also has the ItemTemplate property. What it will do is create one copy of it's ItemTemplate for every item in ItemsSource. The DataContext of the ItemTemplate will be each item in the ItemsSource.

In your case of the ComboBox the DataContext of the DataGrid's column will be your Player object. If you bind the ComboBox's ItemSource to a Player`s Inventory then you will get each item in your ComboBox's list. The thing to note is that the DataContext of the ComboBox itself is unchanged. It is still the Player object. If you specify an ItemTemplate for your ComboBox, that is what will have it's DataContext to the items in a Player's invertory.

Stephan
For SelectedValue, SelectedItem, if we have binding , then it will bind to the property of the datacontext of the combobox(not the property of each item in the itemssource of the combobox). So it is the property of the Player which is the datacontext of the combobox nowFor SelectedValuePath, DisplayMemberPath: we don't use Markup Syntax to assign the value to them so it is not basically binding. That's why we still can assign the name of the property of the item in its itemssource(not the property of the datacontext). Am i right?
Tai
A: 

Its really simple.

DataContext refers to the same property of the items. It does not get extended and its not dynamic. DataContext applies to children's properties which are currently inside the parent.

But ItemsSource is dynamic. It gets extended along with the source. Here is a gud example.

This is a sample xaml.

 <UserControl x:Class="SilverlightApplication"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="400">

<Grid x:Name="LayoutRoot" Background="White">
    <Grid.Resources>           
        <DataTemplate x:Key="template2">
            <StackPanel Orientation="Horizontal">
                <Image x:Name="img1" Source="{Binding Image}"></Image>
                <TextBlock x:Name="data2" Text="{Binding Data}"></TextBlock>
            </StackPanel>
        </DataTemplate>
    </Grid.Resources>
    <StackPanel>
        <StackPanel x:Name="DataContextStack" Orientation="Vertical">
            <TextBlock x:Name="data1" Text="{Binding Text1}"></TextBlock>
            <TextBlock x:Name="data2" Text="{Binding Text2}"></TextBlock>
        </StackPanel>
        <ListBox x:Name="lst2" ItemTemplate="{StaticResource template2}"></ListBox>
    </StackPanel>
</Grid>

Here is the code behind.

 namespace SilverlightApplication
 {
  public partial class MainPage : UserControl
 {
    public MainPage()
    {
        InitializeComponent();
        loadLists();
    }

    private void loadLists()
    {
        ObservableCollection<Temp2> tColl = new ObservableCollection<Temp2>();            

        Temp1 t1 = new Temp1();
        t1.Text1 = "DataContext1";
        t1.Text2 = "DataContext2";            

        tColl.Add(new Temp2() { Image = "", Data = "Item1" });
        tColl.Add(new Temp2() { Image = "", Data = "Item2" });


        DataContextStack.DataContext = t1;
        lst2.ItemsSource = tColl;            
    }
}

public class Temp1
{
    public string Text1 { get; set; }
    public string Text2 { get; set; }



}

public class Temp2
{
    public string Image { get; set; }
    public string Data { get; set; }
}
}

As you can see, the DataContext applies to the Textblocks which exist in the StackPanel and refer to one single property that is Text.

Whereas ItemsSource refers to Source of the Image and Text property of the Textblock and the items inside the list can be extended along with the ObservableCollection.

Or to make it even simpler to you.

DataContext - Value is set based on the design. ItemsSource - Value is set based on the logic.

Hope this helps.

Mark this as answer, if this answered your question.

Aswin Ramakrishnan
Hi Aswin, thank you for your help . I understand your example but what i want to ask is the case for having both itemssource and datacontext for the same control (the case of datagrid with combobox column inside). I think Stephan's answer clears up most of my confusion.your answer is also helpful too . Thank you
Tai
Its the same thing. If you have a listbox with 2 textblocks as I said in the example. You can use DataContext to bind the data. In case it has different controls as its children, then using ItemsSource would be the best option. Both are DataBinding phenomenon used in different scenarios.
Aswin Ramakrishnan