WPF UserControl 依赖属性不起作用 [英] WPF UserControl Dependency Property not working

查看:29
本文介绍了WPF UserControl 依赖属性不起作用的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

在 WPF 项目(下面的代码)中,我有一个 MyUserControl 类型的 UserControl 和一个依赖属性,称为 MyOrientation 类型的 >方向.

In a WPF project (code below) I have a UserControl of type MyUserControl with a dependency property, called MyOrientation of type Orientation.

MainWindow 上,我有 2 个 MyUserControl 实例,其中我通过 XAML 将 Orientation 属性设置为 Horizo​​ntal 和另一个实例是 Vertical.

On the MainWindow I have 2 instances of MyUserControl, where via XAML I set the Orientation property on one to be Horizontal and the other instance to be Vertical.

我已将 MyOrientation 属性设为 DP,因为我希望能够像本示例中那样直接在 XAML 中设置它或使用绑定.

I have made the MyOrientation property a DP as I want the ability to set it directly in XAML as in this example or using a binding.

我的问题是,当我运行项目时,UserControl 的两个实例都显示为 Orientation = Horizo​​ntal?

My problem is that when I run the project both instances of the UserControl show up with the Orientation = Horizontal?

有人能告诉我我做错了什么以及如何解决吗?

Could someone please tell me what I am doing wrong and how to fix it?

非常感谢.

代码如下:

我的用户控制视图模型:

MYUSERCONTROLVIEWMODEL:

public class MyUserControlViewModel : ViewModelBase
{
    private Orientation _myOrientation;
    public Orientation MyOrientation
    {
        get { return _myOrientation; }
        set
        {
            if (_myOrientation == value)
                return;
            _myOrientation = value;
            OnPropertyChanged();
        }
    }

}

MYUSERCONTROL.XAML

MYUSERCONTROL.XAML

<UserControl x:Class="TestUserControlDPProblem.MyUserControl"
         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:local="clr-namespace:TestUserControlDPProblem"
         mc:Ignorable="d" 
         d:DesignHeight="300" d:DesignWidth="300">
<Grid x:Name="root">

    <Grid.DataContext>
        <local:MyUserControlViewModel/>
    </Grid.DataContext>

    <StackPanel Orientation="{Binding MyOrientation}">
        <TextBlock>Hello</TextBlock>
        <TextBlock>There</TextBlock>
    </StackPanel>
</Grid>

MYUSERCONTROL 代码隐藏:

MYUSERCONTROL CODE BEHIND:

public partial class MyUserControl : UserControl
{
    MyUserControlViewModel _vm;

    public MyUserControl()
    {
        InitializeComponent();

        _vm = root.DataContext as MyUserControlViewModel;
    }

    public static readonly DependencyProperty MyOrientationProperty = DependencyProperty.Register("MyOrientation", typeof(Orientation), typeof(MyUserControl), new FrameworkPropertyMetadata(Orientation.Vertical, new PropertyChangedCallback(OnMyOrientationChanged)));

    private static void OnMyOrientationChanged(DependencyObject o, DependencyPropertyChangedEventArgs e)
    {
        var myUserControl = o as MyUserControl;
        myUserControl?.OnMyOrientationChanged((Orientation)e.OldValue, (Orientation)e.NewValue);
    }

    protected virtual void OnMyOrientationChanged(Orientation oldValue, Orientation newValue)
    {
        _vm.MyOrientation = newValue;
    }
    public Orientation MyOrientation
    {
        get
        {
            return (Orientation)GetValue(MyOrientationProperty);
        }
        set
        {
            SetValue(MyOrientationProperty, value);
        }
    }

}

主窗口.XAML

<Window x:Class="TestUserControlDPProblem.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:TestUserControlDPProblem"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525">
<Grid>
    <StackPanel>
        <local:MyUserControl Margin="10" MyOrientation="Horizontal"/>
        <local:MyUserControl Margin="10" MyOrientation="Vertical"/>
    </StackPanel>


</Grid>

推荐答案

UserControl 的内部"视图模型没有意义,不应该存在.您应该改为通过 RelativeSource 或 ElementName 绑定直接绑定到依赖项属性:

The "internal" view model of the UserControl makes no sense and should not be there. You should instead bind directly to the dependency property by means of a RelativeSource or ElementName Binding:

<StackPanel Orientation="{Binding MyOrientation,
                          RelativeSource={RelativeSource AncestorType=UserControl}}">

您甚至不需要 PropertyChangedCallback:

You wouldn't even need the PropertyChangedCallback:

public partial class MyUserControl : UserControl
{
    public MyUserControl()
    {
        InitializeComponent();
    }

    public static readonly DependencyProperty MyOrientationProperty =
        DependencyProperty.Register(
            nameof(MyOrientation), typeof(Orientation), typeof(MyUserControl), 
            new FrameworkPropertyMetadata(Orientation.Vertical));

    public Orientation MyOrientation
    {
        get { return (Orientation)GetValue(MyOrientationProperty); }
        set { SetValue(MyOrientationProperty, value); }
    }
}

这篇关于WPF UserControl 依赖属性不起作用的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆