This is probably a silly question, but I can't make a simple example with ItemsSource work. My XAML:
<Window x:Class="TestDataGrid.MainWindow"
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"
xmlns:local="clr-namespace:TestDataGrid"
mc:Ignorable="d" Height="250" Width="300" Name="MyWindow">
<ListBox ItemsSource="{Binding MyItems, ElementName=MyWindow}" Background="{Binding MyBrush, ElementName=MyWindow}"/>
</Window>
Code:
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private ObservableCollection<Item> items;
public MainWindow()
{
InitializeComponent();
items = new ObservableCollection<Item>();
items.Add(new Item { Key = "Key1", Value = "Value1" });
items.Add(new Item { Key = "Key2", Value = "Value2" });
items.Add(new Item { Key = "Key3", Value = "Value3" });
}
public ObservableCollection<Item> MyItems
{
get { return items; }
}
public Brush MyBrush
{
get { return Brushes.LightPink; }
}
}
public class Item
{
public string Key { get; set; }
public string Value { get; set; }
}
It works if I set ItemsSource in code, or if I set DataContext=this
and then remove ElementName from my binding. But why doesn't it work with ElementName?
I can bind the background color like this, but not collection.
I know how to make it work with DataContext, or in code-behind, but I'm interested in why this particular example doesn't work, am I missing something?
As pointed out by @Clemens your binding will actually work if you populate the source collection before the InitializeComponent() is called.
The difference between setting a DataContext in code behind and creating an ElementName Binding in XAML is that the latter is already established during the
InitializeComponent
call. Items that are added later - to a collection that does not implementINotifyCollectionChanged
- are ignored.You could also bind to the parent window using a RelativeSource though, This works:
You set your
MyItems
after initializing your windows and sinceMyItems
in your example doesn't implement a setter and theINotifyPropertyChanged
manner, your UI thread is never warn by the change you made on your collection.Here two solutions you can set up:
SOLUTION 1
Instantiate your Observable collection directly in the get:
SOLUTION 2
Use
INotifyPropertyChanged
interface:Like that when you set your items, Your UI thread knows there is a change to do in the xaml part