【问题标题】:My WPF user control has one-way bindings and I don't know why我的 WPF 用户控件具有单向绑定,我不知道为什么
【发布时间】:2013-03-04 21:14:59
【问题描述】:

我创建了一个非常简单的用户控件,它显示了一个 ColorPicker(来自 WPF 扩展工具包)和一个十六进制代码的文本字段:

<UserControl x:Class="HexColorPicker"> <!-- namespace declarations omitted -->
    <UserControl.Resources>
        <glue:ColorToRgbHex x:Key="colorToHex"/> <!-- custom converter I made -->
    </UserControl.Resources>
    <StackPanel Orientation="Horizontal" Name="layoutRoot">
        <Label Content="#"/>
        <TextBox Text="{Binding SelectedColor, Converter={StaticResource colorToHex}}"/>
        <extToolkit:ColorPicker SelectedColor="{Binding SelectedColor}"/>
    </StackPanel>
</UserControl>

这是支持代码:

public partial class HexColorPicker : UserControl
{
    public static readonly DependencyProperty SelectedColorProperty
        = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(HexColorPicker));

    public HexColorPicker()
    {
        InitializeComponent();
        layoutRoot.DataContext = this;
    }

    public Color SelectedColor
    {
        get { return (Color)GetValue(SelectedColorProperty); }
        set { SetValue(SelectedColorProperty, value); }
    }
}

layoutRoot.DataContext 的恶作剧来自this place I found

然后我像这样使用我的控件:

<me:HexColorPicker SelectedColor="{Binding MyColor}"/>

而且它有点工作。文本字段和颜色选择器是同步的:当一个改变时,另一个也改变。但是,控件和模型对象不是双向同步的:如果我更改模型对象的 MyColor 属性,我的控件将更新,但当我使用我的控件更改它时,MyColor 属性不会更新。

我做错了什么?为什么从我的模型到我的控件的绑定是单向的?

【问题讨论】:

    标签: c# wpf data-binding user-controls


    【解决方案1】:

    将您的 DependencyProperty 声明更改为:

    public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof (Color), typeof (HexColorPicker), new FrameworkPropertyMetadata(default(Color),FrameworkPropertyMetadataOptions.BindsTwoWayByDefault));
    

    【讨论】:

    • 微软的人认为默认情况下不应该是双向的,这让我有些惊讶。
    • @zneak 在很多情况下TwoWay 没有真正意义。
    • 我真的想不出任何情况下控件想要修改自身的属性但不将其同步回模型。我可以想象,双向绑定对于控件不会自行更改的属性没有用处,但正因为如此,它也不会有害。
    • @zneak 我猜单向绑定比双向绑定更轻量级。并且仅对单向有意义的属性的百分比高于其对应属性。
    【解决方案2】:

    我记得,类型之间转换的绑定有时默认为OneWay 绑定。

    来自 BindingMode.Default (http://msdn.microsoft.com/en-us/library/system.windows.data.bindingmode.aspx) 的参考:

    使用绑定目标的默认模式值。每个依赖属性的默认值都不同。通常,用户可编辑的控件属性(例如文本框和复选框的属性)默认为双向绑定,而大多数其他属性默认为单向绑定。确定依赖属性默认绑定单向还是双向的一种编程方法是使用 GetMetadata 获取属性的属性元数据,然后检查 BindsTwoWayByDefault 属性的布尔值。

    问题似乎在于您的控件不被视为“用户可编辑”控件。

    最简单的解决方案是在绑定中指定Mode=TwoWay

    【讨论】:

    • “最简单的解决方案是在绑定中指定 Mode=TwoWay”。那是错误的。如果您希望您的依赖属性绑定双向默认情况下,实现此目的的唯一方法是设置FrameworkPropertyMetadataOptions.BindsTwoWayByDefault 标志,如另一个答案所示。
    • 重新考虑默认部分。
    猜你喜欢
    • 1970-01-01
    • 2011-01-16
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2011-09-29
    • 2020-05-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多