首页 > 解决方案 > WPF 不会始终刷新组合框项目列表

问题描述

我正在 WPF 中做一个小宠物项目,我对此很陌生。

我的(部分)目标如下:

  1. 打开主窗口,其中包含两个标记为系统和文档的组合框
  2. 加载此窗口后,我连接到一个 .mdb 文件,该文件包含一个带有 System 和 Document 列的表。
  3. 它创建存储在数据库文件中的所有不同系统名称的 ObservableCollection,并将它们存储为我的“系统”组合框绑定到的 arrayList。它成功填满组合框并选择列表的第一个成员作为选定项。
  4. “System”组合的 selectedItem 是 OneWayToSource 绑定到名为 SystemFilter 的字符串。每当我更改选择时,此字符串都会成功更新。
    1. 使用此 SystemFilter,我设法过滤文档并获取存储在 TitleList 可观察集合中的相关标题列表,并正确填充“文档”组合框。

它工作正常,但是每次我过滤数据库时,我都会创建与文件的连接,过滤内容提取​​它并关闭连接。在这里,为了避免每次都打开此连接,我决定将所有项目加载到一个名为 DocumentList 的 ObservableCollection 中,并打算在其上运行 LINQ 查询。以及我存储在绑定到组合框的列表中的查询结果。问题:但是在这种情况下,当我选择另一个系统时,组合框项目列表不想自动更新。这可能是什么原因?

/注意:我在 BaseViewModel 中应用了 INotifyPropertyChanged,并使用 FodyWeaver 来编织我的程序集)

原始工作版本:

当我更改为新版本时,我首先成功地用文档填写了 DocumentList。GetListofTitle2 方法:

        internal static void GetListOfTitle2()
    {

        TitleList = (from s in DocumentList where s.System == $"{SystemFilter}" select s.Title).ToList();

    }

和:

        public static ObservableCollection<DocumentModel> DocumentList { get; set; } = new ObservableCollection<DocumentModel>();
    //--------------------------------------------------------------------------------------------//
    public static string SystemFilter { get; set; } = String.Empty;
    //--------------------------------------------------------------------------------------------//

    public static List<string> TitleList { get; set; } = new List<string>();

在这个新版本中,TitleList 再次正确更新,但在界面上没有更新:/ 有什么问题?我想解决它,因为此解决方案似乎比每次打开连接并加载 .mdb 文件时更干净

感谢您提前回答

更新:如果我修改第二个版本仍然使用 observableCollections 并修改 GetListofTitle2 如下:

        public static void GetListOfTitle2()
    {
        TitleList =new ObservableCollection<string>((from s in DocumentList where s.System == $"{SystemFilter}" select s.Title).ToList());
    }

即使 TitleList 包含正确的项目,它仍然不会更新组合框。

标签: c#wpf

解决方案


  1. 如果您更改模型中的实例TitleList,模型应该实现INotifyPropertyChanged接口,并且您必须按照此处PropertyChanged的说明触发一个事件(此外,在此之后,请查看此处)。
  2. 如果引用TitleList保持不变但发生变异(添加或删除元素),则它必须实现INotifyCollectionChanged,而这正是ObservableCollection做什么。

这段代码:

TitleList = new ObservableCollection<string>(...);

属于第 1类:您更改TitleList实例。

但是您使用不触发PropertyChanged事件的自动属性,因此不会刷新绑定:

// this is an auto-property
public List<string> TitleList { get; set; }

// it's equivalent to:
private List<string> _titleList;
public List<string> TitleList
{
  get => _titleList;
  set => _titleList = value;
}    

您必须在块中触发一个PropertyChanged事件:set

private List<string> _titleList;
public List<string> TitleList
{
  get => _titleList;
  set
  {
    // if the new value is the same as the old, just do nothing
    if (Equal(_titleList, value))
      return;

    _titleList = value;
    // This call will raise the event
    NotifyPropertyChanged();
  }
} 

推荐阅读