views:

16

answers:

2

Dear all, 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:XamlGeneratedNamespace="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

+3  A: 

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">

HTH,
Kent

Kent Boogaart
Kent: thank you very much for this super fast answer. I will be away from my desk 1 or 2 days but after my return I will try it out.
bash74
Kent: I had a chance to try your solution. It works perfectly. Thank you very much. Now I only have to figure out how to define these things in Blend (which produced the xaml).
bash74
A: 

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

bash74