【问题标题】:Specify Binding of DependencyProperty in UserControl itself在 UserControl 本身中指定 DependencyProperty 的绑定
【发布时间】:2016-01-09 15:54:24
【问题描述】:

跟进我之前的问题 (Change brushes based on ViewModel property)

在我的 UserControl 中,我有一个 DependencyObject。我想将该对象绑定到我的ViewModel 的属性。在本例中为CarViewModel,属性名称为Status,并返回一个枚举值。

public partial class CarView : UserControl
{
    public CarStatus Status
    {
        get { return (CarStatus)GetValue(CarStatusProperty); }
        set { SetValue(CarStatusProperty, value); }
    }

    public static readonly DependencyProperty CarStatusProperty =
        DependencyProperty.Register("Status", typeof(CarStatus), typeof(CarView), new PropertyMetadata(OnStatusChanged));

    private static void OnStatusChanged(DependencyObject obj, DependencyPropertyChangedEventArgs args)
    {
        var control = (CarView)obj;
        control.LoadThemeResources((CarStatus)e.NewValue == CarStatus.Sold);
    }

    public void LoadThemeResources(bool isSold)
    {
        // change some brushes
    }
}


<UserControl x:Class="MySolution.Views.CarView"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
             xmlns:views="clr-MySolution.Views"
             mc:Ignorable="d"
             views:CarView.Status="{Binding Status}">   
    <UserControl.Resources>
    </UserControl.Resources>
    <Grid>
        <TextBlock Text="{Binding Brand}"FontSize="22" HorizontalAlignment="Center" VerticalAlignment="Center"/>
    </Grid>
<UserControl

我需要在哪里指定这个绑定?在 UserControl 的根目录中,它给出了一个错误:

在“CarView”类型中找不到可附加属性“Status”

在我的 MainWindow 中,我使用 ContentControl 绑定 CarView:

<ContentControl
    Content="{Binding CurrentCar}">
    <ContentControl.Resources>
        <DataTemplate DataType="{x:Type viewmodel:CarViewModel}">
            <views:CarView />
        </DataTemplate>
    </ContentControl.Resources>
</ContentControl>

我的视图模型:

[ImplementPropertyChanged]
public class CarViewModel
{
    public Car Car { get; private set; }

    public CarStatus Status
    {
        get
        {
            if (_sold) return CarStatus.Sold;
            return CarStatus.NotSold;
        }
    }
}

【问题讨论】:

  • 我对 MVVM 很放心,但我看不出你在用 ContentControl 做什么。在 ContentControl 内部有一个 DataTemplate 仅适用于 CarView(DataType 属性用于选择而不是实例化),并且与 CurrentCar 属性的绑定应该有一个 DataContext 对象——我仍然不知道它是如何提供的。如果您想为您的 ViewModel 提供 XAML:。但我更喜欢用 C# 来做:更短,有时你必须在 CS 中处理 VM。

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


【解决方案1】:

你的绑定写得不好。而不是写views:CarView.Status="{Binding Status}" 你应该只写Status="{Binding Status}"

【讨论】:

  • 如果我这样做,我会得到一个不同的错误:“在类型 'UserControl' 中找不到属性 'Status'”和错误:“XML 命名空间中不存在属性 'Status' schemas.microsoft.com/winfx/2006/xaml/presentation'。”
  • 您可以做的事情是从 userControl 继承。然后定义你的依赖属性是你新定义的类。然后在定义控件时不要使用打开的 标记,而是使用 carView 的新标记实例,例如 然后 Status 属性将可用
【解决方案2】:

您的控件似乎正在绑定到自身。
在 CarView 中查找状态。

您的控件 CodeBehind 中应该有一行代码,例如:

this.DataContext = new ViewModelObjectWithStatusPropertyToBindFrom();

问候

【讨论】:

  • 我已经更新了我的问题,我没有在代码中设置 DataContext。我在 XAML 中设置它。
  • 很好,也许你应该显示代码。您的 DataContext 对象是否具有 Status 属性?根据您的错误消息,DataContext 似乎确实是 userControl。如果你遵循 MVVM,DataContext 应该是一个 VM 对象
  • CurrentCar 是 CarViewModel 类型的对象
  • 用户/自定义控件不需要设置 它自己的 DataContext托管控件的控件负责设置DataContext。否则,您的控制权与特定的视图模型实现相关联,而情况并非如此。
  • 是的,你是对的,迈克。我的意思是,我更喜欢通过 C# 提供数据而不是 XAML
猜你喜欢
  • 2012-06-06
  • 2013-06-03
  • 2014-06-22
  • 2016-05-13
  • 1970-01-01
  • 1970-01-01
  • 2013-01-20
  • 2018-11-23
相关资源
最近更新 更多