【问题标题】:Combobox is not refreshing in WPF using MVVM组合框在使用 MVVM 的 WPF 中不刷新
【发布时间】:2015-09-12 00:33:30
【问题描述】:

我有一个类似How to get an ItemsSource to refresh its bind?的问题

但我确实使用了 INotifyPropertyChange 接口,但问题仍然存在。这是 XAML:

<UserControl x:Class="Sample.Module.Pages.View.ModifyDataTypeView"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:Controls="http://metro.mahapps.com/winfx/xaml/controls"
         xmlns:Dialog="clr-namespace:MahApps.Metro.Controls.Dialogs;assembly=MahApps.Metro"
         xmlns:local="clr-namespace:Sample.Module.Pages.ViewModel"
         mc:Ignorable="d" 
         d:DesignHeight="500" d:DesignWidth="350">
<UserControl.DataContext>
    <local:DataTypeViewModel/>
</UserControl.DataContext>
<Canvas>
        <ComboBox Canvas.Left="0" Canvas.Top="0" 
                  Margin="13,22,0,0"
                  Style="{DynamicResource VirtualisedMetroComboBox}"
                  Controls:TextBoxHelper.Watermark="Autocompletion"
                  DisplayMemberPath="DataTypeName"
                  IsEditable="True"
                  ItemsSource="{Binding DataTypes}"
                  MaxDropDownHeight="125"
               SelectedItem="{Binding Path=SelectedDataType, Mode=TwoWay}" Height="25"/>
        </Canvas>

这是视图模型:

 public class DataTypeViewModel : DomainObject
{
    private ObservableCollection<DataTypeRepository> dataTypes;
    private DataTypeRepository selectedDataType;
    private DataTypeModel dataTypeModel;

    public DataTypeViewModel()
    {
        dataTypeModel = new DataTypeModel();
        selectedDataType = new DataTypeRepository();
        this.dataTypes = dataTypeModel.GetAllDataTypes();
        InsertDataTypeCommand = new DelegateCommand(OnInsertDataType);
    }
    public ObservableCollection<DataTypeRepository> DataTypes 
    { 
        get { return dataTypes; }
        set 
        {
            if (!EqualityComparer<ObservableCollection<DataTypeRepository>>.Default.Equals(dataTypes,value))
            {
                dataTypes = value;
                RaisePropertyChanged("DataTypes");
            }
        }
    }

    public DataTypeRepository SelectedDataType
    {
        get
        {
            return selectedDataType;
        }
        set
        {
            if (!EqualityComparer<DataTypeRepository>.Default.Equals(selectedDataType, value))
            {
                selectedDataType = value;
                InsertDataTypeCommand.RaiseCanExecuteChanged();
                RaisePropertyChanged("SelectedDataType");
            }
        }
    }
    public DelegateCommand InsertDataTypeCommand { get; private set; }
    private void OnInsertDataType()
    {
        DataBaseOperationStatusMessage = dataTypeModel.InsertDataType(selectedDataType);
        DatabaseOperationComplete = true;
        DataTypes = dataTypeModel.GetAllDataTypes();
    }
}

请注意,InsertDataTypeCommand 命令在应用程序的另一个选项卡中使用,其中添加了“DataType”。添加数据类型后,用户单击修改选项卡可在组合框列表中查看新的数据类型。但这并没有发生。如果您重新启动应用程序并转到“修改”页面,您可以看到新记录。 问题是即使在使用 INotifyPropertyChange 时,组合框也没有更新。

我在这里错过了什么?

【问题讨论】:

  • ObservableCollection 属性应该是只读的。绝对没有必要使用启用 INPC 的属性来公开它们。如果您想从集合中添加/删除项目,只需使用普通的集合方法。这可能与您的问题有关。
  • 我明白你在说什么。所以你建议将 ObservableCollection 的属性更改为 List?我这样做没有任何效果。
  • 在哪里... 如何... 谁.... 我说 what??? 让我再次阅读我的评论... 嗯,属性应该是只读的,是啊……不用了,INPC,好吧……用普通的收集方法,嗯……我相信这里的问题是你高。请把碗递过来。
  • 我正在尝试解决这里的问题并寻求帮助。如果你觉得这很有趣,那就去别处大笑吧。
  • 试着阅读我的评论并按照它的建议去做。尽量不要做它不建议做的事情。它可能会对你有所帮助。

标签: wpf mvvm data-binding combobox refresh


【解决方案1】:

尝试更新您的绑定以包含更新触发器...

SelectedItem="{Binding Path=SelectedDataType, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"

【讨论】:

  • 实际上问题不在于更新集合,即 DataTypes;不是选择。
【解决方案2】:

我猜想以下行不会导致集合被更新:

 DataTypes = dataTypeModel.GetAllDataTypes(); 

从您的代码看来,您将新项目插入数据库或任何地方,然后运行从数据库加载所有项目的方法。当您插入数据库时​​,创建相应的 DataTypeRepository 项并将其添加到集合中,而不是运行该方法会更好。

this.DataTypes.Add(new DataTypeRepository { property1= "somedata"}); 

这只是意味着,如果您将一个新项目添加到可能是一个巨大的项目列表中,您将不必重新加载所有内容。

您可能还应该将您的 itemsource 更新为 2 路绑定(除非您正在执行 Will 在 cmets 中建议的只读)并将 updatetrigger 设置为已更改的属性(我认为默认情况下它的焦点丢失)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2014-03-30
    • 1970-01-01
    • 2017-09-02
    • 2012-12-16
    • 2015-07-02
    • 2010-10-28
    • 2012-02-29
    相关资源
    最近更新 更多