如何在 WPF 中创建可绑定属性?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/17629945/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 09:12:43  来源:igfitidea点击:

How to create a bindable property in WPF?

c#wpfbinding

提问by Ali Jalali

i have a user control. I want to create a bindable property in my user control. I create a DependencyProperty as follows:

我有一个用户控件。我想在我的用户控件中创建一个可绑定的属性。我创建一个 DependencyProperty 如下:

public static readonly DependencyProperty DateProperty =
    DependencyProperty.Register("Date", typeof(DateTime), typeof(DaiesContainer), 
        new UIPropertyMetadata(DateTime.Now));

    public DateTime Date
    {
        get { return (DateTime)GetValue(DateProperty); }
        set
        {
            SetValue(DateProperty, value);
        }
    }

I then use it in my XAML:

然后我在我的 XAML 中使用它:

<ctrls:DaiesContainer  Date="{Binding Date, Mode=OneWay}"/>

In my ViewModel, the get method of the Date property is called. But in my user control, Date property is not set to a value.

在我的 ViewModel 中,调用了 Date 属性的 get 方法。但是在我的用户控件中,Date 属性未设置为值。

回答by Clemens

Your dependency property implementation is missing a PropertyChangedCallbackthat gets called when the value of the property has changed. The callback is registered as a static method, which gets the current instance (on which the property has been changed) passed as its first parameter (of type DependencyObject). You have to cast that to your class type in order to access instance fields or methods, like show below.

您的依赖属性实现缺少PropertyChangedCallback在属性值更改时调用的。回调被注册为静态方法,它获取当前实例(其属性已更改)作为其第一个参数(类型DependencyObject)传递。您必须将其转换为您的类类型才能访问实例字段或方法,如下所示。

public static readonly DependencyProperty DateProperty =
    DependencyProperty.Register("Date", typeof(DateTime), typeof(DaiesContainer),
    new PropertyMetadata(DateTime.Now, DatePropertyChanged));

public DateTime Date
{
    get { return (DateTime)GetValue(DateProperty); }
    set { SetValue(DateProperty, value); }
}

private void DatePropertyChanged(DateTime date)
{
    //...
}

private static void DatePropertyChanged(
    DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    ((DaiesContainer)d).DatePropertyChanged((DateTime)e.NewValue);
}


Please note also that setting a default value of the dependency property is only done once for all instances of your class. Setting a value of DateTime.Nowwill hence produce the same default value for all of them, namely the time at which the static DependencyPropertyis registered. I guess using something more meaningful, perhaps DateTime.MinValue, would be a better choice. As MinValueis already the default value of a newly created DateTimeinstance, you may even omit the default value from your property metadata:

另请注意,对您的类的所有实例仅设置一次依赖项属性的默认值。DateTime.Now因此,设置一个值将为所有这些生成相同的默认值,即静态DependencyProperty注册的时间。我想使用更有意义的东西,也许DateTime.MinValue,会是一个更好的选择。由于MinValue已经是新创建DateTime实例的默认值,您甚至可以从属性元数据中省略默认值:

public static readonly DependencyProperty DateProperty =
    DependencyProperty.Register("Date", typeof(DateTime), typeof(DaiesContainer),
    new PropertyMetadata(DatePropertyChanged));

回答by Kurubaran

Make your binding Mode TwoWay

使您的绑定模式双向

<ctrls:DaiesContainer  Date="{Binding Date, Mode=TwoWay}"/>

回答by kmatyaszek

I think that you have error in XAML UserControl.

我认为您在 XAML UserControl 中有错误。

You should binding by ElementName, e.g.:

你应该绑定ElementName,例如:

<UserControl x:Class="WPFProject.DaiesContainer"
             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" 
             mc:Ignorable="d" 
             d:DesignHeight="300" d:DesignWidth="300"
             x:Name="daiesContainer">
    <Grid>
        <DatePicker SelectedDate="{Binding Date, ElementName=daiesContainer}" />
    </Grid>
</UserControl>

In this case you binding to Dateproperty of DaiesContainerclass.

在这种情况下,您绑定到类的Date属性DaiesContainer

If you use binding without ElementName:

如果您使用没有绑定ElementName

<DatePicker SelectedDate="{Binding Date}" />

UserControl DaiesContainerwill trying find property Datein DataContextof container this user control, and if it will not find this property, you will see DatePickerwith empty selected value.

UserControl DaiesContainer将尝试DateDataContext此用户控件的容器中查找属性,如果找不到此属性,您将看到DatePicker空的选定值。