3

ある種の拡張ComboBoxであるWPFusercontrolでの醜い競合状態があります。UserControlは主に2つのバインド可能なDependencyPropertiesを定義します。1つは選択されたアイテムで、もう1つは選択されたアイテムを選択できるリストです。両方ともバインド可能であるため、コントロールは選択されたアイテムの有無にかかわらず初期化でき、両方のプロパティはバインドを介して(DataContextの変更時に)変更できます。さらに、ユーザーの操作により選択が変更される場合があります。UserControlにはComboBoxが含まれており、そのItemsSourceとSelectedItemは、UserControlのプロパティとSelectedItemのリストと同期されています。ここでの問題は、両方の値が設定された新しいDataContextを設定するときに、両方のプロパティが外部から(ほぼ同時に)変更された場合、

簡単に言うと、リストの更新中にSelectedItemを「ロック」する方法を見つける必要がありますが、更新後に受信するため、PropertyChanged-Eventsを観察するだけでは不十分であり、記憶する状態はすでに失われています。さらに、選択の変更がユーザーによって引き起こされたのか、(正しく)バインディングによって引き起こされたのか、(望ましくない)他のバインディングによって間接的に引き起こされたのかを特定できません...DependencyPropertiesのBe​​forePropertyChangedまたはOnPropertyChangingイベントが必要になると思います-または別の両方のプロパティの同時更新の順序を管理する方法。

どんな提案も歓迎します:)

アイテムを選択するためのリストについて話しますが、実際には、迅速な並べ替えとフィルタリングを可能にするより複雑な構造であることに注意してください。これは、ここでItemsControlを使用しない理由でもありますが、そのようには感じません。質問に関連します。

4

1 に答える 1

1

これは状況を改善しない可能性があり、おそらくこれを行う正しい方法ではありませんが、OnPropertyChanging依存関係プロパティのイベントについて話しました。

たまたま、依存関係プロパティを作成するPropertyMetadataときに、プロパティが変更されたときに起動するコールバックを指定できます。このコールバックには、古い値と新しい値の両方が含まれていますEventArgument

コールバックを使用したTextプロパティの例を次に示します

public static DependencyProperty TextProperty = DependencyProperty.Register
                                                ("Text", typeof(string), 
                                                 typeof(DecimalTextBox), 
                                                 new PropertyMetadata("", OnTextPropertyChanged));

最後のパラメータはあなたが探しているものです。PropertyMetadataコンストラクターの最初のパラメーターは、プロパティのデフォルト値です。2つ目は、プロパティが変更されたときに発生するpropertychangedコールバックを登録する場所です。

このコールバックでは、バインディングを処理して、データコンテキストのSelectedItemを上書きしないようにすることができます。

private static void OnTextPropertyChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
    {

        var box = ((TextBox)sender);

        if (((string)e.NewValue)==badvalue)
                box.Text= e.OldValue);


    }

正直なところ、null値が有効かどうかを確認する方法がまだわからないため、これが状況にどのように役立つかはわかりません。(ItemsSourceが変更されたばかりでない限り、ItemsSourceがある場合はnull値を許可しない可能性があります[そして、選択されたアイテムが変更されるとリセットされるItemsSource変更コールバックで何らかのフラグを使用する可能性があります])。私は非同期についてあまり手がかりがありませんが、おそらくここに何らかのロックを入れることができます。

u_u

于 2012-03-19T12:16:14.003 に答える