【问题标题】:Why can't I Bind a viewmodel property to a dependency property of a custom control为什么我不能将视图模型属性绑定到自定义控件的依赖属性
【发布时间】:2010-03-31 12:03:44
【问题描述】:

我想在我的 wpf 应用程序中使用颜色选择器,我在 this codeproject 页面上看到了一个漂亮的颜色选择器。在我想将控件连接到视图模型之前,该控件可以正常工作。 我用这个视图模型创建了一个小测试程序:

public class ColorViewModel : ViewModelBase
{
    public ColorViewModel()
    {
        LineColor = Brushes.Yellow;
    }

    SolidColorBrush _brushColor;
    public SolidColorBrush LineColor
    {
        get { return _brushColor; }
        set
        {
            _brushColor = value;
            RaisePropertyChanged(() => LineColor);
        }
    }
}

测试程序有一个文本框和颜色选择器控件:

<StackPanel Orientation="Horizontal">
    <TextBlock Text="Please Select a Color" FontWeight="Bold" Margin="10"
               Foreground="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged}"/>
     <vw:ColorPickerControlView x:Name="ForeColorPicker" Margin="10"
               CurrentColor="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged }"/>
</StackPanel>

在我的测试应用程序主窗口的加载事件中,我将视图模型设置为 datacontext,如下所示:

 DataContext = new ColorViewModel();

问题是我似乎无法将视图模型的 LineColor 属性绑定到 ColorPickerControlView 的 CurrentColor 属性。 ColorPickerControlView 的 CurrentControl 属性似乎很好。构造函数如下所示:

public ColorPickerControlView()
{
    this.DataContext = this;
    InitializeComponent();
    CommandBindings.Add(new CommandBinding(SelectColorCommand, SelectColorCommandExecute));
}

在 UserControl 的构造函数中有一行 this.DataContext = this;我读到这是绑定依赖属性所必需的。当我将我的视图模型设置为数据上下文时,我是否会覆盖这一行,这就是我无法绑定到 CurrentColor 属性的原因吗?有什么解决方法吗?还是我又犯了一个错误?

【问题讨论】:

    标签: c# wpf data-binding mvvm dependency-properties


    【解决方案1】:

    您认为 UserControl 的构造函数中的 DataContext=this 短语在绑定到外部视图模型时会抢占您的想法是正确的。它在this question 中讨论过。然而,这很容易解决。 xaml 绑定到的 UserControl 代码中只有一个 DependencyProperty:CurrentColor。

    这样做:

    • Name="Root" 属性添加到 UserControl 的 xaml
    • 更改(边框标签的)属性 Background="{Binding Path=CurrentColor}" 至:

      Background="{Binding ElementName=Root, Path=CurrentColor}"

    • 删除有问题的 DataContext=this 来自 UserControl 的行 构造函数!

    这应该就是它的全部了。我写了一个概念证明来证明上述内容。如果你喜欢我可以发布它,但上面的代码应该是你所需要的。

    【讨论】:

    • 有效!谢谢!我会将这个讨论的链接发送给创建颜色选择器的人。
    【解决方案2】:

    两个绑定必须与设置属性的值发生冲突。尝试设置Mode=OneWay

    <StackPanel Orientation="Horizontal">
        <TextBlock Text="Please Select a Color" FontWeight="Bold" Margin="10"
                   Foreground="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"/>
         <vw:ColorPickerControlView x:Name="ForeColorPicker" Margin="10"
                   CurrentColor="{Binding Path=LineColor, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay }"/>
    </StackPanel>
    

    【讨论】:

      【解决方案3】:

      这行 this.DataContext = this 并不是真正需要的,因为您将 DataContext 替换为 ViewModel 的实例。您也不需要在 Loaded 事件处理程序上分配 DataContext。只需在构造函数上设置它。您可以在调用 InitializeComponent 方法后设置它。

      【讨论】:

      • 实际上,他没有用 ViewModel 的实例替换 DataContext,所以绑定是相对于控件本身...
      • 好的,我得再看看他的帖子。他确实说过在窗口的 Loaded 事件处理程序中他这样做了: DataContext = new ColorViewModel();这是否意味着它没有被替换?是不是有什么不被替换的原因?
      • 我想我不清楚。行 DataContext = new ColorViewModel() 在我的测试应用程序中,它将视图模型附加到主窗口。 this.DataContext=this;是颜色选择器控件的构造函数中的一行。 Dabblernl的回答解决了我的问题。
      • 好的,感谢您的澄清。我想我没有完全理解它。无论如何,我很高兴你已经解决了你的问题。
      【解决方案4】:
      1. 删除文件 ColorPickerControlView.xaml.cs 中的 DataContext = this 行
      2. 将 ColorPickerControlView.xaml 中的 Binding 更改为 Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type CustomWPFColorPicker:ColorPickerControlView}}, 路径=当前颜色}"

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 2012-08-29
        • 2010-12-16
        • 2011-12-21
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多