2010-05-27 24 views
5

Ich habe ein WPF UserControl, das eine DependencyProperty (MyProperty) enthält.Binding-Wert ändern, nicht verbindlich

Die DependencyProperty ist an eine Eigenschaft im DataContext gebunden.

Jetzt im UserControl möchte ich den Wert der gebundenen Eigenschaft ändern. Aber wenn ich MyProperty = NewValue zuweisen, wird die Bindung verloren und durch NewValue ersetzt.

Was ich erreichen möchte, ist die DataContext-Eigenschaft zu ändern, an die die DependencyProperty gebunden ist.

Wie erreiche ich das, anstatt die Bindung zu ändern?

Um zu verdeutlichen: mit etwas wie MyTextBox.Text = "0"; werde ich die Bindung freigeben. Wie würde ich Text setzen, lassen Sie die Bindung intakt, damit sich auch die Eigenschaft Text ändern kann.

Antwort

3

Ich kann nicht sagen, was Sie falsch machen, ohne Ihren Code zu sehen. Im Folgenden finden Sie eine einfache Benutzersteuerung, mit der Benutzer eine Farbe auswählen können.

<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, Modus = TwoWay behoben mein Problem, danke !!! – Sam

1

Dies sollte funktionieren, wie es ist, das einzige Problem ist, dass die Bindungsquelle, an die das Textfeld gebunden ist, aktualisiert wird, wenn das Textfeld den Fokus verliert. Dies ist das Standardverhalten. Sie können es ändern, indem Sie UpdateSourceTrigger=PropertyChanged innerhalb Ihrer Bindung angeben. Wie so:

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

Sie können SetCurrentValue verwenden.

Die SetCurrentValue-Methode ändert den effektiven Wert der Eigenschaft, aber vorhandene Trigger, Datenbindungen und Stile funktionieren weiterhin.

+1

Das hat dasselbe wie direkte Zuweisung zu der Eigenschaft getan: Auf OneWay-Bindung löschte es die Bindung, auf TwoWay-Bindung änderte es die gebundene Eigenschaft. – Sam

+0

Wow. Danke für den Kommentar, Sam. Ein riesiges Kopfweh von einem Problem, das ich hatte. Ich war mir nicht bewusst, dass das Festlegen der Werte auf der Zielseite einer OneWay-Bindung die Bindung löschte. Ich habe eine Ereignis- und Set-Funktion für den Quellpfad verwendet und versucht, die Bindung nur auf dem Rückweg zu verwenden. Es hat nicht funktioniert, bis ich es auf TwoWay gesetzt habe. –

+0

Da man keine TwoWay-Bindung für Style-Trigger angeben kann, ist dies einfach genial. Vielen Dank – LuckyLikey

Verwandte Themen