C# WPF UserControl依赖项属性不工作

C# WPF UserControl依赖项属性不工作,c#,wpf,xaml,user-controls,wpf-controls,C#,Wpf,Xaml,User Controls,Wpf Controls,在WPF项目(下面的代码)中,我有一个UserControl类型的MyUserControl,它具有一个依赖属性,名为MyOrientation,类型为Orientation 在main窗口上我有两个MyUserControl实例,通过XAML我在其中一个实例上将Orientation属性设置为水平,另一个实例设置为垂直 我已经将MyOrientation属性设置为DP,因为我希望能够像本例中那样直接在XAML中设置它,或者使用绑定 我的问题是,当我运行项目时,UserControl的两个实例都

在WPF项目(下面的代码)中,我有一个
UserControl
类型的
MyUserControl
,它具有一个依赖属性,名为
MyOrientation
,类型为
Orientation

main窗口上
我有两个
MyUserControl
实例,通过XAML我在其中一个实例上将
Orientation
属性设置为
水平
,另一个实例设置为
垂直

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

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

有人能告诉我我做错了什么以及如何修复它吗

非常感谢

代码如下:

MYUSERCONTROLVIEWMODEL:

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

}
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>
MAINWINDOW.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>

用户控件的“内部”视图模型毫无意义,不应该存在。您应该通过RelativeSource或ElementName绑定直接绑定到dependency属性:

<StackPanel Orientation="{Binding MyOrientation,
                          RelativeSource={RelativeSource AncestorType=UserControl}}">
UserControl的“内部”视图模型毫无意义,不应该存在。您应该通过RelativeSource或ElementName绑定直接绑定到dependency属性:

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

谢谢你的回复。你的改变确实起到了作用。我想说,实现“内部”视图模型是为了让UserControl拥有自己的DataContext。或者,不管怎样,这就是目的。我仍然不明白为什么我的代码不起作用,但是,你永远不应该这样做。DataContext应该只从UserControl的父元素继承,UserControl应该只公开绑定到继承的DataContext中的视图模型对象属性的依赖属性。这些绑定不应该在UserControl的XAML中声明为“内部”,而是当控件在某处使用时。我试图遵循Brian Noyes的博客中给出的建议:我没有读过它,但如果它建议UserControl应该有自己的视图模型,那就大错特错了。不要相信互联网上的一切。有很多由“专家”撰写的博客展示了带有私有视图模型的用户控件。阅读这些博客的人往往会在这里结束,他们会问为什么他们对UserControl的依赖属性的绑定不起作用。谢谢你的回答。你的改变确实起到了作用。我想说,实现“内部”视图模型是为了让UserControl拥有自己的DataContext。或者,不管怎样,这就是目的。我仍然不明白为什么我的代码不起作用,但是,你永远不应该这样做。DataContext应该只从UserControl的父元素继承,UserControl应该只公开绑定到继承的DataContext中的视图模型对象属性的依赖属性。这些绑定不应该在UserControl的XAML中声明为“内部”,而是当控件在某处使用时。我试图遵循Brian Noyes的博客中给出的建议:我没有读过它,但如果它建议UserControl应该有自己的视图模型,那就大错特错了。不要相信互联网上的一切。有很多由“专家”撰写的博客展示了带有私有视图模型的用户控件。阅读这些博客的人往往会在这里结束,他们会问为什么他们对UserControl的依赖属性的绑定不起作用。
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); }
    }
}