当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

当ObservableCollection的内容被改变时,难以更新UI

我假设您的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();
    }

和最后一行将组合框设置回最初选择的项。

那么简单。:)