更改绑定值,而不是绑定自身

时间:2022-11-12 14:58:06

I've got a WPF UserControl containing a DependencyProperty (MyProperty).

我有一个包含DependencyProperty(MyProperty)的WPF UserControl。

The DependencyProperty is bound to a Property in the DataContext.

DependencyProperty绑定到DataContext中的Property。

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.

现在在UserControl中我想更改bound属性的值。但是,如果我指定MyProperty = NewValue,则绑定将丢失并由NewValue替换。

What I want to achieve is change the DataContext-property the DependencyProperty is bound to.

我想要实现的是更改DependencyProperty绑定的DataContext属性。

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.

澄清:使用类似MyTextBox.Text =“0”的东西;我将发布绑定。我如何设置Text,保持绑定完整,因此绑定的属性也将更改。

3 个解决方案

#1


3  

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;
            }
        }
    }
}

#2


4  

You can use SetCurrentValue.

您可以使用SetCurrentValue。

The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.

SetCurrentValue方法更改属性的有效值,但现有的触发器,数据绑定和样式将继续工作。

#3


1  

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:

这应该按原样工作,唯一的问题是当文本框失去焦点时,文本框绑定的绑定源将被更新。这是默认行为。您可以通过在绑定中指定UpdateSourceTrigger = PropertyChanged来更改它。像这样:

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

#1


3  

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;
            }
        }
    }
}

#2


4  

You can use SetCurrentValue.

您可以使用SetCurrentValue。

The SetCurrentValue method changes the effective value of the property, but existing triggers, data bindings, and styles will continue to work.

SetCurrentValue方法更改属性的有效值,但现有的触发器,数据绑定和样式将继续工作。

#3


1  

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:

这应该按原样工作,唯一的问题是当文本框失去焦点时,文本框绑定的绑定源将被更新。这是默认行为。您可以通过在绑定中指定UpdateSourceTrigger = PropertyChanged来更改它。像这样:

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