tags:

views:

100

answers:

3

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.

+1  A: 

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}"/>
repka
+2  A: 

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"&gt;

    <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;
            }
        }
    }
}
Wallstreet Programmer
Aahh, Mode=TwoWay fixed my problem, thanks!!!
Sam
+1  A: 

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.

Kris
This did the same as direct assignment to the Property: On OneWay-binding it dropped the binding, on TwoWay-binding it changed the bound property.
Sam
Wow. Thank you for the comment, Sam. Cleared up a huge headache of a problem I was having. I didn't realize that setting the value on the target side of a OneWay binding cleared the binding. I was using an event and Set function on the source bound path and trying to use the binding only on the way back. It wasn't working until I set it to TwoWay.
Josh G