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を実装します。これは、更新が必要であることをUIに通知するためにWPFの内部が依存するものです。

PortListにINotifyPropertyChangedを実装することでこれを回避しようとしているようですが、これは希望どおりに機能しません。そのインターフェイスは、コンボボックスを更新するための適切なイベントをトリガーしません。INotifyCollectionChangedは、コレクションに変更があること(つまり、「追加」、「削除」、「移動」、「置換」、「リセット」)をリスナーに通知しますが、INotifyPropertyChangedは、バインドされたオブジェクトで一部の値が変更されたことを示すだけです。ComboBoxはINotifyPropertyChangedイベントに応答しません。実際、おそらくそのタイプのイベントにサブスクライブしていません。

したがって、基になるデータソースに直接バインドするか、変更を通知しないIEnumerableだけでなく、その上に2番目のObservableCollectionを実装します。

于 2012-06-05T23:40:36.033 に答える