2012-06-20 17 views
5

Czy można ustawić wartość powiązania dwukierunkowego bezpośrednio, bez znajomości powiązanej właściwości?Ustawia wartość wiązania bezpośrednio

mam załączony właściwość, która jest związana z właściwością tak:

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

Teraz chcę zmienić wartość, która jest skutecznie przechowywane w Something z perspektywy załączonym nieruchomości. Nie mogę uzyskać bezpośredniego dostępu do powiązanej właściwości, ale mam tylko odniesienia do obiektu DependencyObject (tj. Elementu) i obiektu DependencyProperty.

Problem polegający na tym, że ustawienie go po prostu przez DependencyObject.SetValue polega na tym, że skutecznie usuwa to powiązanie, ale chcę zmienić powiązaną właściwość związaną.

Używanie BindingOperations Mogę uzyskać zarówno Binding i BindingExpression. Czy istnieje sposób, aby uzyskać dostęp do nieruchomości za nią i zmienić jej wartość?

+0

Czy napisałeś Załączony-prop się, jak można się zmienić jego PropertyMetadata? Nie sądzę? –

+0

@HellScream Tak, piszę własność, więc mogę zmienić metadane, jeśli to pomaga. – poke

Odpowiedz

3

Ok, mam rozwiązać ten teraz się za pomocą kilku sztuczek refleksyjnych na wyrażeniu wiążącym.

Zasadniczo przyjrzyj się ścieżce wiązania i odpowiadającemu elementowi danych i spróbuj rozwiązać problem samodzielnie. Prawdopodobnie zakończy się to niepowodzeniem w przypadku bardziej złożonych ścieżek wiążących, ale w przypadku prostej nazwy właściwości, jak w moim przykładzie powyżej, powinno to działać poprawnie.

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); 
} 
+0

to nie działa, gdy ścieżka jest złożona. Ponieważ gdy ścieżka jest czymś w rodzaju Customer.Name, rzeczywista właściwość nie istnieje w DataItem BindingExpression. Jest własnością innego obiektu (w tym przypadku przez klienta). –

+0

@KubilayKara Jeśli przeczytasz moją odpowiedź, zauważysz, że powiedziałem, że będzie działać tylko dla prostych nazw właściwości. Jeśli masz złożone ścieżki wiązania, musisz najpierw przeanalizować ścieżkę i przejść przez obiekty, aby znaleźć właściwą właściwość. – poke

0

Co powiesz na przesłanie zależności DependencyObjet do elementu i ustawienie właściwości? Czy to jest możliwe?

+0

Ponieważ właściwość jest własnością związaną, typ elementu nie zawiera takiej właściwości. A "Coś" jest częścią kontekstu danych, do którego nie mam bezpośredniego dostępu, skąd chcę zmienić wartość. – poke

0

Spróbuj ustawić domyślną wartość w PropertyMetadata

można znaleźć więcej informacji na MSDN - http://msdn.microsoft.com/en-us/library/system.windows.propertymetadata.aspx

Oto przykład:

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)); 
+0

Właściwość ma już wartość domyślną, ale chcę zmienić wartość * później *. Ponadto nie sądzę, że wartość domyślna jest w ogóle rozpatrywana, gdy wartość załączonej właściwości jest rzeczywiście ustawione (do wiązania). – poke

0

Problem kiedy po prostu ustawienie go poprzez DependencyObject.SetValue jest że ta skutecznie usuwa wiązania, ale chcę zmienić bazowego związanego nieruchomości.

Jest to prawdziwe, jeżeli tryb Binding.Mode jest ustawiony na OneWay. Jeśli jest ustawiony na TwoWay, użycie DependencyObject.SetValue nie usunie jego powiązania.

To jest cytat z Pro WPF 4.5 w języku C# (strona 232):

Wyjmowanie oprawa: Jeśli chcesz usunąć wiązanie, dzięki czemu można ustawić właściwość w zwykły sposób można potrzebujesz pomocy metody ClearBinding() lub ClearAllBindings(). Nie wystarczy po prostu zastosować nową wartość do właściwości. Jeśli używasz wiązania dwukierunkowego, , ustawiona wartość jest propagowana do połączonego obiektu, a obie właściwości pozostają zsynchronizowane.

Tak, aby móc zmieniać (i propagować) moje: Narzędzia.MyProperty z SetValue bez usuwania wiązania:

<Element my:Utils.MyProperty="{Binding Something, Mode=TwoWay}" /> 
0

Możesz przekazać wartość poprzez wiązanie na sztucznym obiekcie.

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); 
    } 

To mój fikcyjny obiekt

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)); 
} 
Powiązane problemy