1

Value プロパティを DP として定義する DependencyObject があります。また、定義済みの値のフレンドリ名を表す Presets コレクションも定義します。

UI が機能する方法は、Value プロパティにバインドするときです。値がプリセットと一致する場合はフレンドリ名を表示し、それ以外の場合は値を直接表示します。

プリセット (アイテムごとに定義され、共有されていない) を渡し、双方向バインディングを行う信頼できる方法がないため、コンバーターの使用はできません。それを UI でのバインディングに使用し、内部で変換を処理できるようにします。

FriendlyValue は既存の Value DependencyProperty に依存するため、変換ロジックを CLR ゲッター/セッターにラップするだけでよいと考えましたが、これは、実際の値 DP が変更されたときに、FriendlyValue も更新されたことを UI に通知する必要があることを意味します。また、FriendlyValue は CLR プロパティであるため、その特定のプロパティに対して INPC をサポートする必要があります。

私の質問は、これを処理するための正しい/推奨される方法ですか、それとも 2 番目の DP を使用して、その変更ハンドラーを監視し、それに応じて他のプロパティを設定し、状態変数を追加して一方が他方を設定しないようにすることです。最初に、それから再び他のものを更新します。

オブジェクトのプロパティのコードは次のとおりです...

public static readonly DependencyProperty PresetsProperty = DependencyProperty.Register(
    "Presets",
    typeof(List<Preset>),
    typeof(MyObject),
    new UIPropertyMetadata(null));

public List<Preset> Presets
{
    get { return (List<Preset>)GetValue(PresetsProperty); }
    set { SetValue(PresetsProperty, value); }
}

public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
    "Value",
    typeof(string),
    typeof(MyObject),
    new UIPropertyMetadata(null, (s,e) => {

        var myObject = (MyObject)s;

        myObject.OnPropertyChanged("FriendlyValue");

    }));

public string Value
{
    get { return (string)GetValue(ValueProperty); }
    set { SetValue(ValueProperty, value); }
}


public string FriendlyValue
{
    get
    {
        var foundPreset = Presets.FirstOrDefault(preset => preset.Value == this.Value);
        return (foundPreset != null)
            ? foundPreset.FriendlyName
            : this.Value;
    }
    set
    {
        var foundPreset = Presets.FirstOrDefault(preset => preset.FriendlyName == value);

        this.Value = (foundPreset != null)
            ? foundPreset.Value
            : value;

        // Note: We don't raise INPC notification here.  It's raised in the Value's change handler
    }
}

#region INotifyPropertyChanged Members

    public event PropertyChangedEventHandler PropertyChanged;

    protected void OnPropertyChanged(string propertyName)
    {
        if(PropertyChanged != null)
            PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
    }

#endregion

それで、これは組み込みコンバーターの動作の良い習慣と考えられていますか?

4

1 に答える 1

0

ValueFriendlyValue依存関係プロパティの両方を作成してみませんか? 2 つの手法を同時に使用する理由はわかりません。

検討:

using Preset = Tuple<string, string>;

public class MyObject : DependencyObject
{
    private readonly IList<Tuple<string, string>> _presets = new List<Preset> {
        new Preset("1", "good"),
        new Preset("2", "bad"),
    };

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register(
        "Value", typeof(string), typeof(MyObject),
        new PropertyMetadata(null,
            (o, e) => ((MyObject)o).ValuePropertyChanged((string)e.NewValue)));
    private static readonly DependencyProperty FriendlyValueProperty = DependencyProperty.Register(
        "FriendlyValue", typeof(string), typeof(MyObject),
        new PropertyMetadata(null,
            (o, e) => ((MyObject)o).FriendlyValuePropertyChanged((string)e.NewValue)));

    public string Value
    {
        get { return (string)GetValue(ValueProperty); }
        set { SetValue(ValueProperty, value); }
    }

    public string FriendlyValue
    {
        get { return (string)GetValue(FriendlyValueProperty); }
        set { SetValue(FriendlyValueProperty, value); }
    }

    private void ValuePropertyChanged (string newValue)
    {
        var preset = _presets.FirstOrDefault(p => p.Item1 == newValue);
        FriendlyValue = preset != null ? preset.Item2 : newValue;
    }

    private void FriendlyValuePropertyChanged (string newValue)
    {
        var preset = _presets.FirstOrDefault(p => p.Item2 == newValue);
        Value = preset != null ? preset.Item1 : newValue;
    }
}

ノート:

  1. 簡潔にするために簡略化されたプリセットのコード。
  2. 値が変更されていない場合、変更コールバックは呼び出されないため、スタック オーバーフローは発生しません。

あなたの論理を正しく理解できたと思います。問題が 1 つありますFriendlyValue。プリセットのわかりやすい値の 1 つに変更するValueと、見つかったプリセットの値に変更され、次にFriendlyValueプリセットの名前に変更されます。その動作が期待されているかどうかはわかりません。

于 2013-09-11T23:25:49.203 に答える