触发器属性已更改集合中的某个元素



ViewModel中有两个集合,一个是作为DataGrid行源(在本例中只有值 1,2,3,..(,另一个对象表示 DataGrid 中一列的排序器(基于 ID 在属性中公开一些值(。

在下面的示例中,我使用了默认ObservableObjectFullyObservableCollection行为,但也尝试过其他类型的集合,但没有成功。WPF 行为在DataGridComboBoxColumnDataGridTemplateColumn上都进行了测试,并使用ComboBox


视图模型:

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,将从Sequencer集合中返回具有相同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();
}

但是,这意味着我们需要将此特定方法添加到每个模型类中,然后记住在每次 Sequencer 更改时调用它们。

问:当集合更改时,如何自动调用属性更改或如何正确处理此绑定?

对于您发布的问题,非常简单,只需使用ObsevrableCollection而不是List即可。事实上,ObsevrableCollection剂量不仅报告AddRemove,它还报告了通过INotifyCollectionChanged.CollectionChanged事件支持的各种运动。因此,如果使用ObsevrableCollection的索引器来设置元素,则会引发类型NotifyCollectionChangedAction.ReplaceCollectionChanged,绑定引擎将从中很好地处理它。但是读完你的评论后我有点困惑,不能确定这是否真的是你想要的。

您可以通过调用MyList[0].OnPropertyChanged(nameof(Foo.Prop1));来引发属性Prop1的 PropertyChanged 事件。

无需创建TriggerPropertyChanged方法。

这有效,因为在您的示例中,OnPropertyChanged是公共的,可以选择接受描述属性名称的字符串。

最新更新