【问题标题】:ListBox not updated when items added to data source将项目添加到数据源时列表框未更新
【发布时间】:2018-04-20 11:06:41
【问题描述】:

我有一个ListBox,根据在文本框中输入的文本过滤项目(以及按下回车时):

<TextBox DockPanel.Dock="Top" Margin="0,0,0,20" Width="200" HorizontalAlignment="Left" Text="{Binding Path=FilterText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
   <TextBox.InputBindings>
      <KeyBinding Command="{Binding Path=FilterSearchCommand}" Key="Enter" />
   </TextBox.InputBindings>
</TextBox>
<ListBox DockPanel.Dock="Bottom" Name="lbItems" ItemsSource="{Binding Path=MyList, UpdateSourceTrigger=PropertyChanged}" HorizontalAlignment="Stretch">
   <ListBox.ItemTemplate>
      <DataTemplate>
         <StackPanel Width="{Binding ActualWidth, ElementName=lbItems}" Cursor="Hand" Margin="10,10,0,10" VerticalAlignment="Center" MouseLeftButtonUp="UIElement_OnMouseLeftButtonUp">
            <TextBlock Text="{Binding Path=Title}"/>
         </StackPanel>
      </DataTemplate>
   </ListBox.ItemTemplate>
</ListBox>

当在文本框中按下 ENTER 时,将执行以下命令:

FilterSearchCommand = new RelayCommand(() => {
 MyList = new ObservableCollection < MyObject > (MyList.Where(x => x.Title.IndexOf(FilterText, StringComparison.InvariantCultureIgnoreCase) >= 0).ToList());
});

public RelayCommand FilterSearchCommand {
 get;
}
public string FilterText {
 get;
 set;
}
public ObservableCollection < MyObject > MyList {
 get;
 set;
}

基本上输入命令后,ObservableCollection 更新成功,但列表框中的项目保持不变。

有什么想法吗?

【问题讨论】:

  • 如果你只在命令执行时创建新的集合实例,而从不向现有集合添加或删除元素,那么拥有 ObservableCollection 是没有意义的。
  • 您将在这里遇到一些问题 - 搜索时,您将覆盖您的“MyList”对象。所以,一旦你过滤,你就不能取消过滤。你应该考虑使用CollectionViewSource
  • 另外注意,在 ItemsSource 绑定上设置 UpdateSourceTrigger=PropertyChanged 是没有意义的。这里没有效果。
  • @TrialAndError - 你的解决方案成功了。您可以将其添加为我接受的答案吗?

标签: c# .net wpf data-binding listbox


【解决方案1】:

您将在这里遇到一些问题 - 搜索时,您将覆盖您的“MyList”对象。所以,一旦你过滤,你就不能取消过滤。您应该考虑使用CollectionViewSource

【讨论】:

    【解决方案2】:

    你需要实现 INotifyPropertyChanged,在 MyList 的 setter 中你会通知 UI 属性改变了。这是一个例子:

    class MyViewModel : INotifyPropertyChanged
    {
        private ObservableCollection<MyObject> _myList;
    
        public ObservableCollection<MyObject> MyList
        {
            get { return _myList; }
            set
            {
                _myList = value; 
                OnPropertyChanged();
            }
        }
    
        public event PropertyChangedEventHandler PropertyChanged;
    
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
    

    【讨论】:

    • 刚刚尝试过,但没有成功 - 列表框仍未更新
    • 你能发布一些关于你如何实现 INotifyPropertyChanged 的​​代码吗?
    • 你用结果设置_myList还是MyList?
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2016-11-24
    • 1970-01-01
    • 2011-10-18
    • 1970-01-01
    • 1970-01-01
    • 2015-11-15
    • 1970-01-01
    相关资源
    最近更新 更多