【问题标题】:Data Binding on a custom DependenctProperty of a Cutom Shape doesn't work自定义形状的自定义依赖属性上的数据绑定不起作用
【发布时间】:2018-09-03 20:12:28
【问题描述】:

我在 .NET 中相对较新,所以,很可能我在做一些愚蠢的事情,但我所做的只是 我用 XAML 创建了一个自定义形状,它基本上是一个圆形。

Circle.xaml:

<local:Closed2DArea
x:Class="GeoDraw.CustomShapes.Circle"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:GeoDraw.CustomShapes"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
Name="circle">
<Path.Data>
    <EllipseGeometry Center="{Binding Center, ElementName=circle}" RadiusX="{Binding Radius, ElementName=circle}" RadiusY="{Binding Radius, ElementName=circle}"/>
</Path.Data>
</local:Closed2DArea>

现在,Circle.xaml.cs: 文件有两个 DependencyPropertyCenterPropertyRadiusProperty

public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(Circle), null);
    public Point Center
    {
        get => (Point)GetValue(CenterProperty);
        set => SetProperty(CenterProperty, value);
    }
    public static readonly DependencyProperty RadiusProperty = DependencyProperty.Register("Radius", typeof(double), typeof(Circle), null);
    public double Radius
    {
        get => (double)GetValue(RadiusProperty);
        set => SetProperty(RadiusProperty, value);
    }

这里的SetProperty 方法是在基类Closed2DArea 中声明的,它实现了INotifyPropertyChanged,如下所示:

public abstract class Closed2DArea : Path , INotifyPropertyChanged
{
    public event PropertyChangedEventHandler PropertyChanged;

    protected void SetProperty<T>( DependencyProperty prop, T value, [System.Runtime.CompilerServices.CallerMemberName] string propertyName = null)
    {
        SetValue(prop, value);
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
/*constructors and other methods*/
}

当我在具有正常属性设置的视图中使用此形状时,所有这些都可以正常工作,例如 &lt;CustomShape:Circle Center="20 20" Radius="10"&gt;

问题:

当我尝试像这样使用数据绑定时会出现问题:

<Grid x:Name="maingrid" >
    <TextBox x:Name="tbox" Text="80" Margin="258,61,82,189" Width="100" Height="30"/>
    <CustomShape:Circle Center="100,80" Radius="{Binding Text, ElementName=tbox}"/>
</Grid>

这里的绑定不起作用,圆永远不会改变它的半径。我坚持了 5 个小时,尝试了很多,但不知道我错过了什么。有什么帮助吗?

【问题讨论】:

    标签: .net xaml data-binding uwp uwp-xaml


    【解决方案1】:

    您不想将 INotifyPropertyChanged 与依赖属性混合。它们是不同的东西。

    您应该在 VS 中使用propdp 快捷方式,而不是更改它使用的SetValue 函数。

    依赖属性将自动与数据绑定一起使用,这就是额外设置所做的事情。

    INotifyPropertyChanged 用于获取绑定等以使用常规属性。

    我认为您的部分问题是您正在尝试创建一个控件,但使用另一个非DependencyObject 作为基础。要使用依赖属性,您需要从 DependencyObject 继承。通常,当您从 UserControlControl 创建一些东西时,您会得到这个。

    否则,您应该只使用带有 INotifyPropertyChanged 的​​常规属性。

    【讨论】:

    • UseControl 完成了工作!但是你能解释一下为什么Path 不能这样做吗?他们都有DependencyObject在他们的继承。
    【解决方案2】:

    您的依赖属性可能需要在设置其内部值时调用的回调方法,例如:

    public static readonly DependencyProperty CenterProperty = DependencyProperty.Register("Center", typeof(Point), typeof(Circle), new PropertyMetadata(default(Point), CenterPropertyChanged));
    
    private static void CenterPropertyChanged(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs args)
    {
        var circle = dependencyObject as Circle;
        var center = (Point)args.NewValue;
    
        // do something with these values
    }
    

    将所有自定义逻辑从 setter 方法移到此回调方法中 - 数据绑定不会调用您的 setter 方法,而是直接设置依赖属性的值(我猜这就是您所遇到的)。

    【讨论】:

    • RadiusProperty 绑定到EllipseGeometryRadiusXPropertyRadiusYProperty。所以,改变内部值应该改变圆的半径,但事实并非如此。而且,我试过你的解决方案,没有用。圆只是不改变它的半径。
    猜你喜欢
    • 2013-10-16
    • 2017-03-15
    • 1970-01-01
    • 1970-01-01
    • 2011-04-11
    • 2012-08-07
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多