为什么我无法将ViewModel属性绑定到自定义控件的依赖属性?

3

我希望在我的wpf应用程序中使用一个颜色选择器,我在这个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 = new ColorViewModel();

问题在于我似乎无法将视图模型的LineColor属性绑定到ColorPickerControlView的CurrentColor属性。ColorPickerControlView的CurrentControl属性似乎没问题。构造函数如下:
public ColorPickerControlView()
{
    this.DataContext = this;
    InitializeComponent();
    CommandBindings.Add(new CommandBinding(SelectColorCommand, SelectColorCommandExecute));
}

在UserControl的构造函数中,有一行代码 this.DataContext = this;。我了解到这是绑定依赖属性所必需的。当我将我的ViewModel设置为DataContext时,是否需要覆盖此行代码?这就是为什么我无法绑定到CurrentColor属性的原因吗?是否有任何解决方法?或者我犯了其他错误?
4个回答

8
你的想法是正确的,UserControl构造函数中的DataContext=this短语会优先于它绑定到外部视图模型。这在这个问题中有讨论。然而,这很容易解决。UserControl代码后台只有一个依赖属性与xaml绑定:CurrentColor。

请按以下步骤操作:

  • 在UserControl的xaml标记中添加Name="Root"属性
  • 将(Border标记的)属性Background="{Binding Path=CurrentColor}"更改为:

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

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

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


它可以工作了!谢谢!我会把这个讨论链接发送给创建颜色选择器的那个人。 - Robert

0

两个绑定必须冲突以设置属性的值。尝试设置 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>

0

这一行代码 this.DataContext = this 并不是必须的,因为您正在使用ViewModel的实例替换DataContext。您也不需要在Loaded事件处理程序中分配DataContext。只需在构造函数中设置它即可,在调用InitializeComponent方法之后设置即可。


实际上,他并没有用 ViewModel 的实例替换 DataContext,因此绑定是相对于控件本身的... - Thomas Levesque
好的,我得再检查一下他的帖子。他确实在窗口的Loaded事件处理程序中这样做了:DataContext = new ColorViewModel();这是否意味着它没有被替换?它没有被替换的原因是什么? - Michael Detras
我觉得我表达不够清楚。 DataContext = new ColorViewModel() 这行代码在我的测试应用程序中,它将视图模型附加到主窗口。 this.DataContext=this; 是颜色选择器控件构造函数中的一行代码。 Dabblernl 的答案解决了我的问题。 - Robert
好的,谢谢你澄清。我想我没有完全理解它。无论如何,我很高兴你已经解决了问题。 - Michael Detras

0
  1. 在文件ColorPickerControlView.xaml.cs中删除行DataContext = this
  2. 将ColorPickerControlView.xaml中的绑定更改为Background="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type CustomWPFColorPicker:ColorPickerControlView}}, Path=CurrentColor}"

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接