不依赖项属性类型

时间:2020-04-19 12:40:52

标签: c# wpf

为什么类型为XXX的依赖项属性可以获取其他类型的值?

是为默认值定义的依赖项属性的类型吗?

例如:

项目结构:

Project

用户控制代码(CarControl):

XAML代码:

<% for (var chunk in htmlWebpackPlugin.files.chunks) { %>
    <script src="<%= htmlWebpackPlugin.files.chunks[chunk].entry %>"></script>
<% } %>

(C#)后面的代码:

<% for (var chunk in htmlWebpackPlugin.files.js) { %>
    <script src="<%= htmlWebpackPlugin.files.js[chunk]%>"></script>
<% } %>

请注意,此依赖项属性<UserControl x:Class="TypeOfDependencyProperty.Controls.CarControl" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" d:DesignHeight="450" d:DesignWidth="800"> <Grid> <TextBlock Text="{Binding Brand}"/> </Grid> </UserControl> 在此处的类型为using System.Windows; using System.Windows.Controls; namespace TypeOfDependencyProperty.Controls { public partial class CarControl : UserControl { #region Brand public static readonly DependencyProperty BrandProperty = DependencyProperty.Register("Brand", typeof(string), typeof(CarControl), new FrameworkPropertyMetadata((string)string.Empty)); public string Brand { get { return (string)GetValue(BrandProperty); } set { SetValue(BrandProperty, value); } } #endregion public CarControl() { InitializeComponent(); } } }

查看代码(CarView):

XAML代码:

Brand

(C#)后面的代码:

string

查看模型代码(CarViewModel):

<Page x:Class="TypeOfDependencyProperty.Views.CarView"
      xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
      xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
      xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
      xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:controls="clr-namespace:TypeOfDependencyProperty.Controls"
      mc:Ignorable="d" 
      d:DesignHeight="450" d:DesignWidth="800"
      Title="CarView">
    <Grid>
        <controls:CarControl Brand="{Binding Brand}"/>
    </Grid>
</Page>

现在,如果我将类型从using System.Windows.Controls; using TypeOfDependencyProperty.ViewModels; namespace TypeOfDependencyProperty.Views { public partial class CarView : Page { public CarView() { InitializeComponent(); this.DataContext = new CarViewModel(); } } } 更改为namespace TypeOfDependencyProperty.ViewModels { public class CarViewModel { public string Brand { get; set; } public CarViewModel() { Brand = "XXXXXXXXXXXXXXXXXXXXXXXXX"; // Any value } } } (或其他),如下所示,它将继续起作用。

string

当然,我在输出窗口中收到以下错误,但是仍然可以!该值在运行时显示无故障。

System.Windows.Data错误:1:无法创建默认转换器以 在类型“ System.String”和“类型”之间执行“单向”转换 'System.Collections.Generic.List List<XXX> 1')

System.Windows.Data错误:5:BindingExpression生成的值是 对于目标财产无效。价值=“汽车品牌” BindingExpression:Path = Brand; DataItem ='CarViewModel' (HashCode = 14000148);目标元素是'CarControl'(Name ='');目标 属性为“品牌”(类型为“列表`1”)

有人可以解释我吗?这是一个错误吗?

3 个答案:

答案 0 :(得分:1)

绑定

<TextBlock Text="{Binding Brand}"/>

直接绑定到视图模型中的Brand属性。它不使用控件的Brand属性。

因此,当您编写时,它甚至会显示视图模型属性值

<controls:CarControl />

完全不绑定控件的Brand属性。

在控件的XAML中控件属性的正确用法是:

<TextBlock Text="{Binding Brand,
                  RelativeSource={RelativeSource AncestorType=UserControl}}"/>

答案 1 :(得分:-1)

当您说“获取价值”时

在:

为什么类型为XXX的依赖项属性可以获取其他类型的值?

您要问的实际上是如何解决绑定的问题。

WPF框架解析绑定并获取实际的当前值。

解析完成后,框架将尝试“设置”依赖项属性的值,然后才检查类型是否相同。

如果不是,并且没有为绑定提供转换器,它将抛出您添加的此异常。

答案 2 :(得分:-1)

DependecyProperty类型定义了存储在其中的数据的类型。 您只能将相同类型的数据绑定到它。或者,您可以将转换器添加到绑定。为此,您必须实现IValueConverter接口。

但是我不明白您的问题,想要您显示整个列表中的字符串吗?还是要为列表的每个元素创建一个项目?

在第二种情况下,建议您使用ItemsControl并将自定义控件插入ItemTemplate内。

最后,您不必每次都定义默认值,您可以从DependecyProperty初始化中删除PropertyMetadata。并记住,如果定义它,它将是静态的,并且仅在具有基本类型的情况下才会与其他实例发生变化。如果您有一个类,建议您使用null并将其分配给Costructor类。

public static readonly DependencyProperty BrandProperty =
    DependencyProperty.Register("Brand", typeof(List<double>), typeof(CarControl));