2009-08-28 18 views
5

Tengo una propiedad de dependencia de cadenas (SearchText), cuando se actualiza, necesita actualizar una propiedad de dependencia de colecciones (Resultados).
Mi dp colección:Actualizando una propiedad de dependencia de otra

public IEnumerable<string> Results{ 
    get { return (IEnumerable<string>) GetValue(ResultsProperty); } 
    set { SetValue(ResultsProperty, value); } 
} 
public static readonly DependencyProperty ResultsProperty= 
DependencyProperty.Register("Results", typeof(IEnumerable<string>), typeof(MainWindowVM), new UIPropertyMetadata(new List<string>())); 

He intentado esto sin suerte. puse un punto de interrupción en la línea Results = .... y nunca recibió un golpe.

public string SearchText{ 
    get { return (string) GetValue(SearchTextProperty); } 
    set { 
    Results = 
      from T in Tree.GetPeople(value) 
      select T.FullName; 
    SetValue(SearchTextProperty, value); 
    } 
} 
public static readonly DependencyProperty SearchTextProperty= 
DependencyProperty.Register("SearchText", typeof(string), typeof(MainWindowVM), new UIPropertyMetadata("")); 

XAML:

<TextBox DockPanel.Dock="Top" Text="{Binding SearchValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" />

<ListBox DockPanel.Dock="Top" ItemsSource="{Binding NameResults}" SelectedItem="{Binding Search}" />

Respuesta

7

Al establecer una propiedad de dependencia en XAML o por medio de un enlace, el tiempo de ejecución siempre pasará por alto el alias propiedad de instancia y directamente llamar GetValue y SetValue . Es por esto que su instalador de instancias no está siendo invocado.

Lo que puede considerar hacer es registrar un método con la propiedad de dependencia que se invocará cuando la propiedad cambie. Esto se realiza más fácilmente al crear el PropertyMetadata para la propiedad de dependencia.

Creo que el siguiente ejemplo hace lo que estás buscando hacer. En el ejemplo, mi clase tiene dos propiedades de depenncency con alias como Primero y Segundo. Cuando establezco el valor para Primero, mi manejador de cambio es invocado y establezco el valor de Segundo.

public class DependencyPropertyTest : DependencyObject 
{ 
    public static readonly DependencyProperty FirstProperty; 
    public static readonly DependencyProperty SecondProperty; 

    static DependencyPropertyTest() 
    { 
    FirstProperty = DependencyProperty.Register("FirstProperty", 
                typeof(bool), 
                typeof(DependencyPropertyTest), 
                new PropertyMetadata(false, FirstPropertyChanged)); 

    SecondProperty = DependencyProperty.Register("SecondProperty", 
               typeof(string), 
               typeof(DependencyPropertyTest), 
               new PropertyMetadata(null)); 
    } // End constructor 

    private bool First 
    { 
    get { return (bool)this.GetValue(FirstProperty); } 
    set { this.SetValue(FirstProperty, value);  } 

    } // End property First 

    private string Second 
    { 
    get { return (string)this.GetValue(SecondProperty); } 
    set { this.SetValue(SecondProperty, value);   } 

    } // End property Second 

    private static void FirstPropertyChanged(DependencyObject dependencyObject, 
              DependencyPropertyChangedEventArgs ea) 
    { 
    DependencyPropertyTest instance = dependencyObject as DependencyPropertyTest; 

    if (instance == null) 
    { 
     return; 
    } 

    instance.Second = String.Format("First is {0}.", ((bool)ea.NewValue).ToString()); 

    } // End method FirstPropertyChanged 
} // End class DependencyPropertyTest 

Espero que ayude.

+0

-1, Esto romperá la unión en la propiedad 'Second' porque FijarValor se utilizará en lugar de SetCurrentValue (ver http://stackoverflow.com/ questions/4230698/whats-the-difference-between-dependency-property-setvalue-setcurrentvalue). – Benlitz

+3

Es cierto hoy, te lo concederé. Sin embargo, en el momento de escribir esta respuesta, .NET Framework 3.5 era la versión más reciente que no tenía un miembro SetCurrentValue. (ref: https://msdn.microsoft.com/en-us/library/system.windows.dependenobjetos_objetos(v=vs.90).aspx) Bien vale la pena un comentario o una respuesta adicional para modernizar, pero en mi humilde opinión no garantiza un voto negativo. –

5

Como he comentado, la respuesta actualmente aceptada es correcta en el principio, excepto que DEBE usar el método SetCurrentValue en lugar de hacer una asignación simple. Consulte this answer para obtener más explicaciones al respecto.

aquí es el mismo código con esta revisión:

public class DependencyPropertyTest : DependencyObject 
{ 
    public static readonly DependencyProperty FirstProperty; 
    public static readonly DependencyProperty SecondProperty; 

    static DependencyPropertyTest() 
    { 
    FirstProperty = DependencyProperty.Register("FirstProperty", 
                typeof(bool), 
                typeof(DependencyPropertyTest), 
                new PropertyMetadata(false, FirstPropertyChanged)); 

    SecondProperty = DependencyProperty.Register("SecondProperty", 
               typeof(string), 
               typeof(DependencyPropertyTest), 
               new PropertyMetadata(null)); 
    } // End constructor 

    private bool First 
    { 
    get { return (bool)this.GetValue(FirstProperty); } 
    set { this.SetValue(FirstProperty, value);  } 

    } // End property First 

    private string Second 
    { 
    get { return (string)this.GetValue(SecondProperty); } 
    set { this.SetValue(SecondProperty, value);   } 

    } // End property Second 

    private static void FirstPropertyChanged(DependencyObject dependencyObject, 
              DependencyPropertyChangedEventArgs ea) 
    { 
    DependencyPropertyTest instance = dependencyObject as DependencyPropertyTest; 

    if (instance == null) 
    { 
     return; 
    } 

    // SetCurrentValue should be used here! 
    instance.SetCurrentValue(SecondProperty, 
     String.Format("First is {0}.", ((bool)ea.NewValue).ToString()); 

    } // End method FirstPropertyChanged 
} // End class DependencyPropertyTest 
+0

debería ser un comentario! –

Cuestiones relacionadas