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 h
The key control to think about is an ItemsControl
(ComboBox
inherits from ItemsControl
and the DataGrid
behaves very similar).
An ItemsControl
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 inventory.
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.