简体   繁体   English

更改ObservableCollection的内容时难以更新UI?

[英]Difficulty updating UI when contents of ObservableCollection is changed?

I have a combobox bound to an observablecollection as: 我有一个绑定到observablecollection的组合框为:

 <ComboBox 
        HorizontalAlignment="Left" Margin="586,51,0,0" VerticalAlignment="Top" Width="372" 
        SelectedItem="{Binding PrimaryInsurance.SelectedInsurance}"
        ItemsSource="{Binding PrimaryInsurance.AllPatientInsurance}" 
        ItemTemplate="{StaticResource InsuranceTemplate}" />

The observablecollection itself is defined as: observablecollection本身定义为:

 private ObservableCollection<Insurance> _allPatientInsurance;
 public ObservableCollection<Insurance> AllPatientInsurance
    {
        get { return _allPatientInsurance; }
        set { if (_allPatientInsurance == value) return; _allPatientInsurance = value; OnPropertyChanged("AllPatientInsurance"); }
    }

Now Insurance encapsulates data downloaded from the database an adds INotifyPropertyChanged as: 现在,保险封装了从数据库下载的数据,并将INotifyPropertyChanged添加为:

 public string CompanyName
    {
        get { return insurance_View.Companyname; }
        set { if (insurance_View.Companyname == value) return; insurance_View.Companyname = value; OnPropertyChanged("CompanyName"); }
    }

Where insurance_View is the raw data record downloaded from the database. 其中insurance_View是从数据库下载的原始数据记录。

All is good. 一切都很好。

However, in an "UnDo" operation, I would like to replace the edited insurance_View record with its original record like: 但是,在“撤消”操作中,我想用其原始记录替换已编辑的insurance_View记录,例如:

 internal void UnDo()
    {
        insurance_View = (Insurance_View)pre_edit_Insurance_View.Clone();
    }

Although the edited version of insurance_View is correctly changed back to its original form, the display is not being updated. 尽管Insurance_View的编辑版本已正确更改回其原始形式,但显示未更新。 Futhermore, replacing the edited version of insurance with the original version of insurance in the ObservableCollection like: 此外,将ObservableCollection中的保险的原始版本替换为保险的编辑版本,例如:

  AllPatientInsurance.Remove(Old Insurance);
  AllPatientInsurance.Add(New Insurance);

Destroys all the bindings and displays a blank record. 销毁所有绑定并显示空白记录。

So, what is the best way to update the display when the contents of Insurance is changed without destroying the Insurance Object? 因此,当更改保险内容而不破坏保险对象时,更新显示的最佳方法是什么? Is there a better way? 有没有更好的办法?

Edit #1. 编辑#1。 Just to be clear, I am trying to replace the data record within the Insurance object where it is the Insurance object that is bound to the display. 为了清楚起见,我试图替换保险对象内的数据记录,在该数据记录中,保险对象绑定到显示。 I am not wanting to replace the entire collection being displayed. 我不想替换正在显示的整个收藏集。 The only thing that comes to mind is to replace each value of the edited record with its original value, but this seems tedious so I am hoping for a better method. 唯一想到的是用其原始值替换已编辑记录的每个值,但这似乎很繁琐,所以我希望有一个更好的方法。

Edit #2. 编辑#2。 Is there any way to trigger the Insurance setters when the encapsulated Insurance_View record is changed? 封装的Insurance_View记录发生更改时,有什么方法可以触发保险设置者?

Edit #3. 编辑#3。 The insurance template: 保险模板:

        <!--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>

Also, please note that simply removing then adding the same Insurance object results in its disappearance from the combobox drop down. 另外,请注意,简单地删除然后添加相同的保险对象会导致其从组合框下拉菜单中消失。 Example: 例:

    AllPatientInsurance.Remove(SelectedInsurance);
    AllPatientInsurance.Add(SelectedInsurance);

TIA TIA

I suppose your InsuranceTemplate has bindings to the Insurance' properties such as CompanyName and therefore listens to property changed events from the Insurance instance (the template's DataContext). 我想您的InsuranceTemplate绑定了保险的属性(例如CompanyName ,因此侦听了Insurance实例(模板的DataContext)的属性更改事件。 So because the undo operation doesn't change the properties by calling the corresponding setters (but by changing the insurance_view) you have to manually trigger the property changed events ( OnPropertyChanged("CompanyName") and so on) of every changed property after the undo operation to notify the view. 因此,由于撤消操作不会通过调用相应的setter(而是通过更改insurance_view)来更改属性,因此您必须手动触发撤消后每个已更改属性的属性更改事件( OnPropertyChanged("CompanyName")等)操作通知视图。

Track the old insurance in its own observable collection. 在自己的可观察集合中跟踪旧保险。 In your undo, you can assign the old collection to AllPatientInsurance, and let the property do the heavy lifting. 在撤消操作中,您可以将旧集合分配给AllPatientInsurance,然后让该属性完成繁重的工作。

//initialize this elsewhere as appropriate
private ObservableCollection<Insurance> _oldPatientInsurance;

internal void UnDo()
{
    insurance_View = (Insurance_View)pre_edit_Insurance_View.Clone();
    AllPatientInsurance = _oldPatientInsurance;
}

This code does not work because the SelectedInsurance becomes null the moment it is removed from the collection: 此代码不起作用,因为SelectedInsurance从集合中删除后即为null:

 AllPatientInsurance.Remove(SelectedInsurance);
 AllPatientInsurance.Add(SelectedInsurance);

However, if a reference to the SelectedInsurance is kept then it can be added back as so: 但是,如果保留了对SelectedInsurance的引用,则可以这样添加回它:

 SelectedInsurance.Reset();
 var x = SelectedInsurance;
 AllPatientInsurance.Remove(SelectedInsurance);
 AllPatientInsurance.Add(x);
 SelectedInsurance = x;

Where Reset() is 其中Reset()是

 internal void Reset()
    {
        insurance_View = (Insurance_View)pre_edit_Insurance_View.Clone();
    }

and the last line sets the combobox back to the initially selected item. 最后一行将组合框设置回最初选择的项目。

So simple. 很简单。 :) :)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM