I've got a WPF UserControl containing a DependencyProperty (MyProperty).
The DependencyProperty is bound to a Property in the DataContext.
Now in the UserControl I want to change the value of the bound property. But if I assign MyProperty = NewValue
the Binding is lost and replaced by NewValue.
What I want to achieve is change the DataContext-property the DependencyProperty is bound to.
How do I achieve this instead of changing the binding?
To clarify: using something like MyTextBox.Text = "0";
I'll release the binding. How would I set Text, leave the binding intact so the property Text is bound to will change, too.
I can't tell what you are doing wrong without seeing your code. Below is a simple usercontrol that allows users to pick a 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;
}
}
}
}
You can use SetCurrentValue.
The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.
This should work as is, the only problem is that binding source the text box is bound to will be updated when the text box loses focus. This is the default behavior. You can change it by specifying UpdateSourceTrigger=PropertyChanged
within your binding. Like so:
<TextBox Name="MyTextBox" Text="{Binding YourBindingPath, UpdateSourceTrigger=PropertyChanged}"/>
来源:https://stackoverflow.com/questions/2921926/change-binding-value-not-binding-itself