2010-05-27 10 views
5

Tengo un WPF UserControl que contiene una DependencyProperty (MyProperty).Cambiar el valor de enlace, no se vincula a sí mismo

DependencyProperty está vinculado a una propiedad en el DataContext.

Ahora en UserControl deseo cambiar el valor de la propiedad encuadernada. Pero si asigno MyProperty = NewValue, el enlace se pierde y se reemplaza por NewValue.

Lo que quiero lograr es cambiar la propiedad DataContext a la que está sujeta DependencyProperty.

¿Cómo logro esto en lugar de cambiar la unión?

Para aclarar: usando algo como MyTextBox.Text = "0"; Voy a liberar el enlace. Cómo establecería Text, dejaré el enlace intacto para que la propiedad Text también cambie.

Respuesta

3

No puedo decir lo que está haciendo mal sin ver su código. A continuación se muestra un control de usuario simple que permite a los usuarios elegir un color.

<UserControl x:Class="ColorPickerTest.ColorPicker" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 

    <StackPanel Orientation="Horizontal"> 
     <ToggleButton Name="redButton" Content="Red" Click="Button_Click" /> 
     <ToggleButton Name="yellowButton" Content="Yellow" Click="Button_Click" /> 
    </StackPanel> 
</UserControl> 

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Media; 

namespace ColorPickerTest 
{ 
    public partial class ColorPicker : UserControl 
    { 
     public ColorPicker() 
     { 
      InitializeComponent(); 
     } 

     public Brush SelectedColor 
     { 
      get { return (Brush)GetValue(SelectedColorProperty); } 
      set { SetValue(SelectedColorProperty, value); } 
     } 

     public static readonly DependencyProperty SelectedColorProperty = 
      DependencyProperty.Register("SelectedColor", 
             typeof(Brush), 
             typeof(ColorPicker), 
             new UIPropertyMetadata(Brushes.Transparent, OnPropertyChanged)); 

     private void Button_Click(object sender, RoutedEventArgs e) 
     { 
      if (!redButton.IsChecked.GetValueOrDefault() && !yellowButton.IsChecked.GetValueOrDefault()) 
      { 
       SelectedColor = Brushes.Transparent; 
      } 
      else if (!redButton.IsChecked.GetValueOrDefault() && yellowButton.IsChecked.GetValueOrDefault()) 
      { 
       SelectedColor = Brushes.Yellow; 
      } 
      else if (redButton.IsChecked.GetValueOrDefault() && !yellowButton.IsChecked.GetValueOrDefault()) 
      { 
       SelectedColor = Brushes.Red; 
      } 
      else 
      { 
       // redButton.IsChecked.GetValueOrDefault() && yellowButton.IsChecked.GetValueOrDefault()) 

       SelectedColor = Brushes.Orange; 
      } 
     } 

     private static void OnPropertyChanged(object sender, DependencyPropertyChangedEventArgs e) 
     { 
      ColorPicker colorPicker = sender as ColorPicker; 
      colorPicker.redButton.IsChecked = colorPicker.SelectedColor == Brushes.Red || 
               colorPicker.SelectedColor == Brushes.Orange; 
      colorPicker.yellowButton.IsChecked = colorPicker.SelectedColor == Brushes.Yellow || 
               colorPicker.SelectedColor == Brushes.Orange; 
     } 
    } 
} 

<Window x:Class="ColorPickerTest.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:ColorPickerTest="clr-namespace:ColorPickerTest" 
    Height="300" Width="300"> 
    <StackPanel> 
     <ColorPickerTest:ColorPicker SelectedColor="{Binding Path=MyColor, Mode=TwoWay}" /> 
    </StackPanel> 
</Window> 

using System.Windows; 
using System.Windows.Media; 

namespace ColorPickerTest 
{ 
    public partial class Window1 : Window 
    { 
     public Window1() 
     { 
      InitializeComponent(); 

      MyColor = Brushes.Red; 

      DataContext = this; 
     } 

     private Brush _myColor; 
     public Brush MyColor 
     { 
      get { return _myColor; } 
      set 
      { 
       _myColor = value; 
       Background = _myColor; 
      } 
     } 
    } 
} 
+1

Aahh, Mode = TwoWay solucionó mi problema, gracias! – Sam

1

Esto debería funcionar como está, el único problema es que el origen de enlace al que está obligado el cuadro de texto se actualizará cuando el cuadro de texto pierda el foco. Este es el comportamiento predeterminado. Puede cambiarlo especificando UpdateSourceTrigger=PropertyChanged dentro de su enlace. De la misma manera:

<TextBox Name="MyTextBox" Text="{Binding YourBindingPath, UpdateSourceTrigger=PropertyChanged}"/> 
4

Puede usar SetCurrentValue.

El método SetCurrentValue cambia el valor efectivo de la propiedad, pero los desencadenadores existentes, los enlaces de datos y los estilos seguirán funcionando.

+1

Esto hizo lo mismo que la asignación directa a la Propiedad: en OneWay-binding se eliminó el enlace, en TwoWay-binding cambió la propiedad enlazada. – Sam

+0

Wow. Gracias por el comentario, Sam. Despejó un gran dolor de cabeza de un problema que estaba teniendo. No me di cuenta de que establecer el valor en el lado de destino de un enlace OneWay despejó el enlace. Estaba usando un evento y una función Establecer en la ruta de origen enlazada e intento usar el enlace solo en el camino de regreso. No funcionó hasta que lo configuré en TwoWay. –

+0

Como no se puede especificar un enlace de dos vías en Style-Triggers, esto es genial. Gracias – LuckyLikey

Cuestiones relacionadas