Не удается обновить привязку данных WPF с источником объекта - PullRequest
0 голосов
/ 03 августа 2010

Я некоторое время боролся с этой проблемой и много читал, но большинство примеров слишком просты. Я пытаюсь связать очень простую ObservableCollection с DataGrid. Супер простые объекты в коллекции - это «SingleItems», которые определяются следующим образом:

public class SingleItem {
private String _name=null;

public String Name {
  get { return _name; }
  set { _name=value; }
}

public SingleItem(String name) {
  Name=name;
}

Класс ManyItems размещает коллекцию и определяется следующим образом:

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);
}
}

В моем главном окне я просто хочу обновить ManyItems, когда пользователь нажимает кнопку:

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++;
}

}

Наконец, мой XAML выглядит так (сокращенно, где "..."):

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

Когда я запускаю это приложение, сетка показывает SingleItem «внутри», который я создал в конструкторе. Однако никакие изменения в базовых коллекциях не отражены в таблице данных. Я пытался также использовать INotifyPropertyChanged, но безуспешно. Я думаю, что у меня есть серьезная ошибка в моем понимании. Кто-нибудь может объяснить мне, что я делаю не так? Также высоко ценятся онлайн-примеры (где не все делается внутри конструкторов).

Спасибо за вашу помощь, Себастьян

Ответы [ 2 ]

3 голосов
/ 03 августа 2010

Экземпляр ManyItems, который вы изменяете в коде, не является тем же экземпляром, с которым связан ваш XAML. <local:ManyItems/> в Resources вашего Window вызывает создание отдельного отдельного экземпляра ManyItems.

Используйте тот же экземпляр, и он будет работать нормально:

public MainWindow(){
    this.InitializeComponent();
    this.DataContext = _items;
}

А в XAML удалите раздел Resources и измените свой Grid на просто:

<Grid x:Name="LayoutRoot">
0 голосов
/ 04 августа 2010

Я нашел другое решение, где я могу использовать код, сгенерированный Blend. Все остается неизменным, но MainWindow работает так:

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++;
}
}

Главное, что следует отметить, это то, что больше нет объектов недвижимости. Вместо этого код выполняет поиск именованного ресурса ManyItemsDataSource и передает его в ManyItems. @Kent: ваш намек на два разных экземпляра был идеальным, чтобы вернуть меня в нужное русло: -)

Sebastian

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...