0

我正在尝试使用刚刚学习的 LINQ 解决一个简单的问题。

我有一个字符串集合,在这种情况下代表串行端口,它们将显示在控件中,但必须排序。原始集合是未排序的,我不一定要修改它,或者复制它。因此,我创建了一个 IEnumerable 类型的属性并将其绑定到一个 ComboBox。

这很好用,ComboBox 具有正确顺序的正确内容。但是,如果原始集合发生更改,则 a) 当原始集合更改时,ComboBox 没有得到正确通知,或者 b) LINQ 查询没有被刷新。

在尝试了一些不同的事情之后,我看不出下面的代码是如何工作的。我肯定错过了什么。

这里可能有多余的额外代码......无论如何,源代码后面是控件的 XAML:

public partial class MainWindow : Window
{
    ObservableCollection<string> original = new ObservableCollection<string>();
    public ObservableCollection<string> OriginalList {
        get { return (original); }
    }

    private IEnumerable<string> _portList;
    public IEnumerable<string> PortList {
        get { return (_portList); }
    }

    public MainWindow() {
        InitializeComponent();

        original.Add("COM5");
        original.Add("COM1");
        original.Add("COM3");
        original.Add("COM4");
        original.Add("COM2");

        original.CollectionChanged += new NotifyCollectionChangedEventHandler(OriginalChanged);

        _portList = (
            from port in original
            orderby port ascending
            select port
        );

        DataContext = this;
    }

    private void AddPortButton_Click(object sender, RoutedEventArgs e) {
        original.Add("COM2.5");
    }

    void OriginalChanged(Object sender, NotifyCollectionChangedEventArgs args) {
        NotifyPropertyChanged("PortList");
    }

    public event PropertyChangedEventHandler PropertyChanged;
    private void NotifyPropertyChanged(String info) {
        if (PropertyChanged != null) {
            PropertyChanged(this, new PropertyChangedEventArgs(info));
        }
    }
}

XAML:

    <ComboBox Name="SerialPortListBox" ItemsSource="{Binding PortList}" Width="100" />
    <ComboBox Grid.Row="1" Name="OriginalListBox" ItemsSource="{Binding OriginalList}" Width="100" Margin="0,5,0,0"/>
    <Button Grid.Column="1" Name="AddPortButton" Content="Add Port 2.5" Width="100" Margin="10,0,0,0" Click="AddPortButton_Click" />
4

1 回答 1

1

我认为您只能通过将 ComboBox 绑定到ObservableCollection来获得所需的更改通知。此类实现接口INotifyCollectionChanged,这是 WPF 内部依赖于通知 UI 需要更新的接口。

我看到您正试图通过为 PortList 实施INotifyPropertyChanged来解决此问题,但这不会按您想要的方式工作。该界面不会触发适当的事件来触发组合框刷新。INotifyCollectionChanged 告诉侦听器集合发生了变化(即“添加”、“删除”、“移动”、“替换”、“重置”),而 INotifyPropertyChanged 仅指示绑定对象中的某些值已更改。ComboBox 不会响应 INotifyPropertyChanged 事件,实际上它可能甚至没有订阅该类型的事件。

因此,要么直接绑定到底层数据源,要么在此之上实现第二个 ObservableCollection,而不仅仅是一个不通知更改的 IEnumerable。

于 2012-06-05T23:40:36.033 回答