2013-07-31 3 views
2

мне очень интересно, как это работает, потому что у меня MainViewModel, который недвижимости говорят, что под названием SubViewModel, который имеет свойство ObservableCollection (мы будем называть его Property1.)Что происходит внутри, когда вы привязываетесь к ItemSource?

Я реализовал INotifyChangedProperty на все.

My Main Window

<Window .. 
    DataContext="{Binding MainViewModel}" /> 
... 
    <StackPanel DataContext="{Binding SubViewModel}"> 
     <local:SomeControl DataContext="{Binding}" /> 
    </StackPanel> 
</Window> 

И мой UserControl

<UserControl Name="SomeControl"> 
    <DataGrid Name="MyDataGrid" ItemSource="{Binding Property1, Mode=TwoWay}" CurrentCellChanged="TestMethod" /> 
    ... 
</UserControl> 

В моем методе испытаний, так как тест, чтобы выяснить, почему эти изменения не propegating до основной посмотреть модель Я делаю что-то вроде этого

private void TestMethod() 
{ 
    var vm = this.DataContext as SubViewModel; 

    var itemSourceObservableCollection = MyDataGrid.ItemsSource as ObservableCollection<MyType>; 

    //I thought vm.Property1 would be equal to itemSourceObservableCollection 
    //but they are not, itemSourceObservableCollection shows the changes I've made 
    //vm.Property1 has not reflected any changes made, even though I though they were the same item 
} 

Итак, я понял, что ItemSource должен создать копию элемента, к которому вы его привязываете? Я застрял здесь, как вручную уведомлять viewModel о том, что это свойство изменилось и его необходимо обновить? Я думал, что это была работа с INotifyPropertyChanged?

Я думаю, что часть моей проблемы - это отсутствие понимания того, как этот вид работает внутри. Если кто-нибудь может указать на хорошее сообщение в блоге или документацию, чтобы помочь мне понять, почему мой код работает не так, как я ожидал, это было бы здорово.

+2

_The изменения не propegating до основного вида model_ - какие изменения? Afaik 'Mode = TwoWay' не поддерживается для' ItemsSource'. –

+1

_I думал, что это была работа с INotifyPropertyChanged? _ Нет, это работает только в другом направлении (ViewModel -> View). –

+0

@HenkHolterman, wadr, поддерживается на шаблонных деталях –

ответ

1

1) Никакой копии не производится.

2) ObservableCollection будет предлагать изменения, внесенные в коллекцию, а не элементы в коллекции. Таким образом, вы увидите дополнения, удаления и т. Д., Но НЕ изменяет свойства элементов в коллекции.

3) Если вы хотите увидеть изменения, внесенные в отдельные элементы в ObservableCollection, вам необходимо реализовать INotifyPropertyChanged по этим элементам.

0

Здесь на самом деле есть две разные проблемы. Что происходит внутри, когда вы привязываетесь к коллекции? И почему изменения на поверхности пользователя не распространяются обратно на вашу модель просмотра. Основываясь на том, что вы написали, эти две проблемы не связаны, но давайте возьмем их по одному ...

Для первой проблемы ... Когда вы привязываете коллекцию, механизм привязки WPF создает «CollectionView», класса, который опосредует между хранилищем объектов и логическим деревом. Вы можете, при необходимости, получить копию на «CollectionView» с использованием статического метода CollectionViewSource ...

var cvs = CollectionViewSource.GetDefaultView(MyCollectionOfThings); 

Есть несколько интересных свойств в результате, и некоторые из них содержат аксессор записи, которые позволяют вам в каталог измените CollectionView.

Для второй проблемы ... Бизнес-классы в SubViewModel должны наследовать от INotifyPropertyChanged, так что изменения объявляются через механизм привязки WPF. Ваша виртуальная машина должна быть издателем, но также может быть абонентом. Имущество, которое участвует в сантехнике INotifyPropertyChanged получает объявлена ​​как это ...

private string _name; 
    [Description("Name of the driver")] 
    public string Name 
    { 
     [DebuggerStepThrough] 
     get { return _name; } 
     [DebuggerStepThrough] 
     set 
     { 
      if (value != _name) 
      { 
       _name = value; 
       OnPropertyChanged("Name"); 
      } 
     } 
    } 

Этот код публикует изменения, но могут также подписаться на изменения, сделанные на поверхности пользователя путем установки соответствующих атрибутов в вашем Xaml.

Справочная литература: What is a CollectionView? Кроме того, Similar question

 Смежные вопросы

  • Нет связанных вопросов^_^