WPF Databinding with object source fails to update
I have been struggling a while with this problem and read a lot but most of the examples are too simple. I am trying to bind a very simple ObservableCollection to a DataGrid. The super simple objects within the Collection are "SingleItems" which are defined like this:
public class SingleItem {
private String _name=null;
public String Name {
get { return _name; }
set { _name=value; }
}
public SingleItem(String name) {
Name=name;
}
The class ManyItems hosts the Collection and is defined like this:
public class ManyItems{
private ObservableCollection<SingleItem> allItems=new ObservableCollection<SingleItem>();
public ManyItems() {
AllItems.Add(new SingleItem("inside"));//debug code
}
public ObservableCollection<SingleItem> AllItems {
get { return allItems; }
set { allItems=value; }
}
public void AddItem(SingleItem item) {
AllItems.Add(item);
}
}
In my main window I just want to update ManyItems when the user presses a button:
public partial class MainWindow : Window{
int count=0;
ManyItems _items=new ManyItems();
public ManyItems Items {
get { return _items; }
set { _items=value; }
}
public MainWindow(){
this.InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e){
Items.AddItem(new SingleItem("name_"+count));
count++;
}
}
Finally my XAML looks like this (shortened where "..."):
<Window
...
xmlns:local="clr-namespace:DataGridTEst"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:XamlGenerate开发者_开发技巧dNamespace="clr-namespace:XamlGeneratedNamespace" mc:Ignorable="d"
x:Class="DataGridTEst.MainWindow"
x:Name="Window"
Title="MainWindow"
Width="640" Height="480">
<Window.Resources>
<local:ManyItems x:Key="ManyItemsDataSource" d:IsDataSource="True"/>
</Window.Resources>
<Grid x:Name="LayoutRoot" DataContext="{Binding Source={StaticResource ManyItemsDataSource}}">
<Button Content="Button" .... Click="Button_Click"/>
<DataGrid ... ItemsSource="{Binding AllItems}"/>
</Grid>
When I run this app, the grid shows the SingleItem "inside" which I created in the constructor. However no changes to the underlying Collections are reflected in the datagrid. I tried also to use INotifyPropertyChanged but without success. I think I have a grave error in my understanding. Can anybody explain me what I am doing wrong? Also online examples (where not everything is done inside constructors) are greatly appreciated.
Thanks for your help, Sebastian
The instance of ManyItems
that you're modifying in the code behind is not the same instance that your XAML is bound to. The <local:ManyItems/>
in your Window
's Resources
is causing a separate, distinct instance of ManyItems
to be created.
Use the same instance, and it will work fine:
public MainWindow(){
this.InitializeComponent();
this.DataContext = _items;
}
And in the XAML remove the Resources
section and change your Grid
to simply:
<Grid x:Name="LayoutRoot">
I found another solution where I can use the code that is generated by Blend. Everthing stays the same, but the MainWindow works like this:
public partial class MainWindow : Window{
int count=0;
public MainWindow(){
this.InitializeComponent();
}
private void Button_Click(object sender, System.Windows.RoutedEventArgs e){
ManyItems ds=(ManyItems)this.FindResource("ManyItemsDataSource");
ds.AddItem(new SingleItem(count.ToString()));
count++;
}
}
The main thing to note is that there is no Property Items anymore. INstead the code searches for the named resource "ManyItemsDataSource" and casts it to ManyItems. @Kent: your hint with the two different instances was perfect to get me back on track :-)
Sebastian
精彩评论