8

バインドされたプロパティを知らなくても、双方向バインディングの背後にある値を直接設定することは可能ですか?

次のようなプロパティにバインドされた添付プロパティがあります。

<Element my:Utils.MyProperty="{Binding Something}" />

Somethingここで、添付プロパティの観点から効果的に格納される値を変更したいと思います。DependencyObjectしたがって、バインドされたプロパティに直接アクセスすることはできませんが、 (Element インスタンスなど) とDependencyPropertyオブジェクト自体への参照しかありません。

単純に設定する場合の問題DependencyObject.SetValueは、これによりバインディングが効果的に削除されることですが、基になるバインドされたプロパティを変更したいと考えています。

I を使用すると、と のBindingOperations両方を取得できます。その背後にあるプロパティにアクセスしてその値を変更する方法はありますか?BindingBindingExpression

4

6 に答える 6

6

さて、バインディング式にいくつかの反射トリックを使用して、これを自分で解決しました。

私は基本的にバインディング パスと応答するデータ項目を見て、バインディングを自分で解決しようとします。これは、より複雑なバインディング パスでは失敗する可能性がありますが、上記の例のように単純なプロパティ名の場合、これは正常に機能するはずです。

BindingExpression bindingExpression = BindingOperations.GetBindingExpression(dependencyObj, dependencyProperty);
if (bindingExpression != null)
{
    PropertyInfo property = bindingExpression.DataItem.GetType().GetProperty(bindingExpression.ParentBinding.Path.Path);
    if (property != null)
        property.SetValue(bindingExpression.DataItem, newValue, null);
}
于 2012-06-20T14:55:31.653 に答える
0

でデフォルト値を設定してみてくださいPropertyMetadata

詳細については、MSDN を参照してください - http://msdn.microsoft.com/en-us/library/system.windows.propertymetadata.aspx

例を次に示します。

  public Boolean State
  {
    get { return (Boolean)this.GetValue(StateProperty); }
    set { this.SetValue(StateProperty, value); } 
  }
  public static readonly DependencyProperty StateProperty = DependencyProperty.Register(
    "State", typeof(Boolean), typeof(MyStateControl),new PropertyMetadata(myDefaultValue));
于 2012-06-20T14:13:48.300 に答える
0

DependencyObject.SetValue を介して単純に設定する場合の問題は、これによりバインディングが効果的に削除されることですが、基になるバインドされたプロパティを変更したいと考えています。

これは、Binding.Mode が OneWay に設定されている場合に当てはまります。TwoWay に設定されている場合、DependencyObject.SetValue を使用してもバインディングは削除されません。

これは、C# の Pro WPF 4.5 (232 ページ) からの引用です。

バインディングの削除: 通常の方法でプロパティを設定できるようにバインディングを削除する場合は、ClearBinding() または ClearAllBindings() メソッドの助けが必要です。プロパティに新しい値を適用するだけでは十分ではありません。双方向バインディングを使用している場合、設定した値はリンクされたオブジェクトに伝達され、両方のプロパティは同期されたままになります。

そのため、バインディングを削除せずに SetValue を使用して my:Utils.MyProperty を変更 (および伝播) できるようにするには、次のようにします。

<Element my:Utils.MyProperty="{Binding Something, Mode=TwoWay}" />
于 2016-11-01T21:32:34.997 に答える
0

You can pass value via a binding on a dummy object.

    public static void SetValue(BindingExpression exp, object value)
    {
        if (exp == null)
            throw new ValueCannotBeNullException(() => exp);
        Binding dummyBinding = new Binding(exp.ParentBinding.Path.Path);
        dummyBinding.Mode = BindingMode.OneWayToSource;
        dummyBinding.Source = exp.DataItem;
        SetValue(dummyBinding, value);
    }

    public static void SetValue(Binding binding, object value)
    {
        BindingDummyObject o = new BindingDummyObject();
        BindingOperations.SetBinding(o, BindingDummyObject.ValueProperty, binding);
        o.Value = value;
        BindingOperations.ClearBinding(o, BindingDummyObject.ValueProperty);
    }

This is my dummy object

   internal class BindingDummyObject : DependencyObject
{
    public object Value
    {
        get
        {
            return (object)GetValue(ValueProperty);
        }
        set
        {
            SetValue(ValueProperty, value);
        }
    }

    public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(object), typeof(BindingDummyObject));
}
于 2017-12-15T10:02:39.720 に答える