Триггер PropertyChanged определенного элемента в коллекции - PullRequest
0 голосов
/ 23 июня 2018

Имея две коллекции в ViewModel, одна работает как источник строк для DataGrid (в этом случае имеют только значения 1,2,3, ..), а другие объект, который представляет секвенсор для одного столбца в DataGrid (на основе идентификатора выставить некоторое значение в свойстве).

В приведенном ниже примере я использовал поведение по умолчанию ObservableObject и FullyObservableCollection, но это также было опробовано с другими типами коллекций, но безуспешно. Поведение WPF было протестировано на DataGridComboBoxColumn и DataGridTemplateColumn с ComboBox.


ViewModel:

public class ViewModel : ObservableObject
{
    private FullyObservableCollection<Seq> mSequencer;
    public FullyObservableCollection<Seq> Sequencer
    {
        get { return mSequencer; }
        set { SetProperty(ref mSequencer, value); }
    }

    private FullyObservableCollection<RowSrc> mRowSource;
    public FullyObservableCollection<RowSrc> RowSource
    {
        get { return mRowSource; }
        set { SetProperty(ref mRowSource, value); }
    }
}

Определения классов:

public class Seq : ObservableObject
{
    private int mId;
    public int Id
    {
        get { return mId; }
        set { SetProperty(ref mId, value); }
    }

    private string mName;
    public string Name
    {
        get { return mName; }
        set { SetProperty(ref mName, value); }
    }
}

public class RowSrc : ObservableObject
{
    private int mValue;
    public int Value
    {
        get { return this.mValue; }
        set { SetProperty(ref mValue, value); }
    }
}

Просмотр - XAML:

<CollectionViewSource x:Key="Proxy" Source="{Binding Sequencer}"/>

<DataGrid ItemsSource="{Binding RowSource}">
  <DataGrid.Columns>
    <DataGridComboBoxColumn
                    ItemsSource="{Binding Source={StaticResource Proxy}"
                    SelectedValueBinding="{Binding Value}"
                    SelectedValuePath="Id"
                    DisplayMemberPath="Name"/>
    </DataGridComboBoxColumn>
  </DataGrid.Columns>
</DataGrid>

Исходя из вышесказанного, сетка данных инициализируется со значениями RowSource, которые будут проходить через туннель привязки к Proxy, что приведет к Sequencer. Исходя из Value каждой строки, объект с таким же Id будет возвращен из коллекции Sequencer.

Как есть, при первом запуске все работает хорошо. Проблема начинается, когда мы хотим очистить секвенсор и заполнить его снова.

Sequencer.Clear();
Sequencer.AddRange(...);

Теперь элементы в Sequencer обновляются, однако связь между Row[n].Combobox и элементами в Sequencer НЕ ОБНОВЛЯЕТСЯ . Причина этого в том, что сами свойства не изменились, только элементы в коллекции.


Обходной путь - взломать:

public class RowSrc
{
    ...

    public void InvokeChange()
    {
        OnPropertyChanged(nameof(Value));
    }
}

public class ViewModel
{
    Sequencer.Clear();
    Sequencer = GenerateNewCollection();

    //after update of Sequencer
    foreach (var nRowSrc in RowSrc) nRowSrc.InvokeChange();
}

Однако это означает, что нам нужно будет добавить этот конкретный метод к каждому из наших классов Model, а затем не забывать вызывать их при каждом изменении Sequencer.

В: Как автоматически вызывать изменение свойства при изменении коллекции ИЛИ как правильно обрабатывать эту привязку?

Ответы [ 2 ]

0 голосов
/ 25 июня 2018

Вы можете вызвать событие PropertyChanged для своей собственности Prop1, позвонив по номеру MyList[0].OnPropertyChanged(nameof(Foo.Prop1));.

Нет необходимости создавать TriggerPropertyChanged метод.

Это работает, потому что в вашем примере OnPropertyChanged является общедоступным и, необязательно, принимает строку, описывающую имя свойства.

0 голосов
/ 25 июня 2018

Для проблемы, которую вы разместили, очень просто, просто используйте ObsevrableCollection вместо List. На самом деле, ObsevrableCollection доза не только сообщает Add и Remove, она сообщает обо всех видах движения, которые поддерживают событие INotifyCollectionChanged.CollectionChanged. Таким образом, если вы используете индексатор ObsevrableCollection для установки элемента, CollectionChanged типа NotifyCollectionChangedAction.Replace будет повышен, и механизм привязки с этим справится. Но я немного растерялся после прочтения вами комментария и не уверен, действительно ли это то, что вы хотите.

...