当ObservableCollection的内容被改变时,难以更新UI
本文关键字:更新 UI 改变 ObservableCollection | 更新日期: 2023-09-27 18:09:52
我有一个组合框绑定到一个observablecollection:
<ComboBox
HorizontalAlignment="Left" Margin="586,51,0,0" VerticalAlignment="Top" Width="372"
SelectedItem="{Binding PrimaryInsurance.SelectedInsurance}"
ItemsSource="{Binding PrimaryInsurance.AllPatientInsurance}"
ItemTemplate="{StaticResource InsuranceTemplate}" />
observablecollection本身定义为:
private ObservableCollection<Insurance> _allPatientInsurance;
public ObservableCollection<Insurance> AllPatientInsurance
{
get { return _allPatientInsurance; }
set { if (_allPatientInsurance == value) return; _allPatientInsurance = value; OnPropertyChanged("AllPatientInsurance"); }
}
现在Insurance封装从数据库下载的数据,并添加INotifyPropertyChanged为:
public string CompanyName
{
get { return insurance_View.Companyname; }
set { if (insurance_View.Companyname == value) return; insurance_View.Companyname = value; OnPropertyChanged("CompanyName"); }
}
其中insurance_View为从数据库下载的原始数据记录。
一切都好。
但是,在"撤销"操作中,我想将编辑过的insurance_View记录替换为其原始记录,如:
internal void UnDo()
{
insurance_View = (Insurance_View)pre_edit_Insurance_View.Clone();
}
尽管编辑过的insurance_View版本被正确地更改回其原始形式,但显示并未更新。此外,用ObservableCollection中的原始保险版本替换已编辑的保险版本,如:
AllPatientInsurance.Remove(Old Insurance);
AllPatientInsurance.Add(New Insurance);
销毁所有绑定并显示空白记录。
那么,当Insurance的内容发生变化而不破坏Insurance对象时,更新显示的最佳方法是什么呢?有没有更好的办法?
编辑# 1。为了清楚起见,我试图替换Insurance对象中的数据记录,其中绑定到显示的是Insurance对象。我不想替换正在展示的整个收藏。唯一想到的是将编辑记录的每个值替换为其原始值,但这似乎很繁琐,所以我希望有更好的方法。
编辑# 2。在封装时是否有办法触发Insurance设置Insurance_View记录被更改?
编辑# 3。保险模板:
<!--DataTemplate for the Combobox Insurance List-->
<DataTemplate x:Key="InsuranceTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="20" />
<ColumnDefinition Width="120" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="14" />
<ColumnDefinition Width="50" />
<ColumnDefinition Width="60" />
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding XNotInEffect}" Grid.Column="0" />
<TextBlock Text="{Binding CompanyName}" Grid.Column="1"/>
<TextBlock Text="{Binding EffectiveDateFrom}" Grid.Column="2"/>
<TextBlock Text="--" Grid.Column="3" />
<TextBlock Text="{Binding EffectiveDateTo}" Grid.Column="4" />
<TextBlock Text="{Binding InsuranceType}" Grid.Column="5"/>
</Grid>
</DataTemplate>
另外,请注意,简单地删除然后添加相同的Insurance对象会导致其从组合框下拉列表中消失。例子:
AllPatientInsurance.Remove(SelectedInsurance);
AllPatientInsurance.Add(SelectedInsurance);
TIA
我假设您的InsuranceTemplate
绑定到保险的属性,如CompanyName
,因此从Insurance
实例(模板的DataContext)侦听属性更改事件。因此,由于撤销操作不会通过调用相应的setter(但通过更改insurance_view)来更改属性,因此您必须在撤销操作后手动触发每个更改属性的属性更改事件(OnPropertyChanged("CompanyName")
等)以通知视图。
在它自己的可观察集合中跟踪旧保险。在撤消过程中,您可以将旧集合分配给AllPatientInsurance,并让属性完成繁重的工作。
//initialize this elsewhere as appropriate
private ObservableCollection<Insurance> _oldPatientInsurance;
internal void UnDo()
{
insurance_View = (Insurance_View)pre_edit_Insurance_View.Clone();
AllPatientInsurance = _oldPatientInsurance;
}
这段代码不起作用,因为SelectedInsurance在从集合中删除时变为null:
AllPatientInsurance.Remove(SelectedInsurance);
AllPatientInsurance.Add(SelectedInsurance);
但是,如果保留了对SelectedInsurance的引用,则可以将其添加回:
SelectedInsurance.Reset();
var x = SelectedInsurance;
AllPatientInsurance.Remove(SelectedInsurance);
AllPatientInsurance.Add(x);
SelectedInsurance = x;
其中Reset()是
internal void Reset()
{
insurance_View = (Insurance_View)pre_edit_Insurance_View.Clone();
}
和最后一行将组合框设置回最初选择的项。
那么简单。:)