ViewModel
中有两个集合,一个是作为DataGrid
的行源(在本例中只有值 1,2,3,..(,另一个对象表示 DataGrid 中一列的排序器(基于 ID 在属性中公开一些值(。
在下面的示例中,我使用了默认ObservableObject
和FullyObservableCollection
行为,但也尝试过其他类型的集合,但没有成功。WPF 行为在DataGridComboBoxColumn
和DataGridTemplateColumn
上都进行了测试,并使用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
剂量不仅报告Add
和Remove
,它还报告了通过INotifyCollectionChanged.CollectionChanged
事件支持的各种运动。因此,如果使用ObsevrableCollection
的索引器来设置元素,则会引发类型NotifyCollectionChangedAction.Replace
的CollectionChanged
,绑定引擎将从中很好地处理它。但是读完你的评论后我有点困惑,不能确定这是否真的是你想要的。
您可以通过调用MyList[0].OnPropertyChanged(nameof(Foo.Prop1));
来引发属性Prop1
的 PropertyChanged 事件。
无需创建TriggerPropertyChanged
方法。
这有效,因为在您的示例中,OnPropertyChanged
是公共的,可以选择接受描述属性名称的字符串。