c# - 如何设置依赖属性值?

标签 c# wpf xaml data-binding dependency-properties

请引用下面的代码了解上下文。

  • 启动时,2 个文本框的文本将为“This is the Original Value”。
  • TestBox 的按钮(“测试按钮”)被点击时:
    • TestBoxTextBox 的文本将更改为“Set By Test Button”
    • 另一个文本框的值不会改变。
  • 单击窗口 的按钮时,两个文本框的文本应该更改为“Set By Window”。 但是,只有普通的 TextBox 得到更新,TestBox 没有。 <-- 这就是错误!

似乎我在 TestBox 中(重新)设置 Test 属性的方式消除了绑定(bind)。

在不破坏绑定(bind)的情况下从用户控件本身更改依赖属性的正确方法是什么?


示例代码:

我有一个 UserControl,TestBox,如下所示:

测试框.xaml:

<UserControl x:Class="Company.UserControls.TestBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             x:Name="TextBoxControl">
    <StackPanel>
        <TextBox MinWidth="100" Name="TestTextBox" 
            Text="{Binding Path=Test, ElementName=TextBoxControl, Mode=TwoWay}" 
         />
        <Button MinWidth="100" Content="Test Button" 
            Click="ButtonBase_OnClick" />
    </StackPanel>
</UserControl>

TestBox.xaml.cs:

using System.Windows;

namespace Company.UserControls
{
    public partial class TestBox
    {
        public const string TestString = "Set By Test Button";

        public TestBox()
        {
            InitializeComponent();
        }
        public static readonly DependencyProperty TestProperty = 
                DependencyProperty.Register(
                    "Test", 
                    typeof(string), typeof(TestBox),
            new FrameworkPropertyMetadata(null, 
                        FrameworkPropertyMetadataOptions.AffectsRender));
        public string Test
        {
            get { return (string)GetValue(TestProperty); }
            set { SetValue(TestProperty, value); }
        }
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            /****** THIS OBLITERATES THE BINDING ******/
        Test = TestString;
            /****** THIS OBLITERATES THE BINDING ******/
        }
    }
}

还有一个像这样使用控件的窗口:

主窗口.xaml:

<Window x:Class="Company.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:u="clr-namespace:Company.UserControls"
        Title="MainWindow">
    <StackPanel x:Name="MyStackPanel">
        <TextBox Text="{Binding Path=MyTestValue, Mode=OneWay}"/>
        <u:TestBox x:Name="MyTestBox" 
                   Test="{Binding Path=MyTestValue, Mode=OneWay}"/>
        <Button Content="Click" Click="ButtonBase_OnClick" />
    </StackPanel>
</Window>

MainWindow.xaml.cs:

using System.Windows;

namespace Company
{
    public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();

            MyStackPanel.DataContext = new MyThing
            {
                MyTestValue = "This is the Original Value"
            };
        }
        private void ButtonBase_OnClick(object sender, RoutedEventArgs e)
        {
            MyStackPanel.DataContext = new MyThing
            {
                MyTestValue = "Set by Window"
            };
        }
    }

    public class MyThing
    {
        public string MyTestValue { get; set; }
    }
}

最佳答案

问题是您要求绑定(bind)系统不同步。整个系统旨在使所有绑定(bind)元素保持同步。只有当绑定(bind)模式设置为“TwoWay”或“OneWayToSource”时,您才能在不破坏基础绑定(bind)的情况下为依赖项属性设置值。在这些条件下,值(value)被传输回源,因此,系统保持同步。但是,在您的情况下,双向绑定(bind)将导致两个按钮都更改两个文本框。

您将需要使用两个依赖属性 TestBox。第一个依赖属性将绑定(bind)到内部文本框,第二个将绑定(bind)到父窗口。然后,您需要将属性更改处理程序添加到第二个依赖项属性(在 FrameworkPropertyMetadata 中完成)。在此处理程序中,只需设置第一个依赖项属性的值即可。

由于您使用的是带有隐藏代码的 UserControl,因此一个更简单的解决方案是仅具有上面提到的第二个依赖属性,并通过其直接将值(来自您的事件处理程序和属性更改处理程序)设置到文本框上x:姓名。

如果您需要更多说明,请告诉我。

关于c# - 如何设置依赖属性值?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/24374746/

相关文章:

c# - 如何在 FormBorderStyle 属性设置为 None 时移动 Windows 窗体?

c# - WPF Caliburn.Micro 和带有 UserControls 问题的 TabControl

c# - 当我在 gridview 中单击 linkbutton 时如何获取行索引

c# - 使用 RadialGradientBrush 绘制球体

c# - 如何利用 MVVM Light EventToCommand 在 XAML 中绑定(bind)大量相同的事件?

c# - 关闭一个窗口后关闭 WPF 中的所有窗口

wpf - 如何避免默认情况下在wpf Listbox中选择第一项?

wpf - 如何向 WPF 中的可编辑组合框添加焦点样式

c# - 在C#中使用Emgu.Cv设计的分水岭函数

c# - WPF Xaml 中的命名空间冲突