在样式中绑定Canvas.Left和Canvas.Top

3
我正在尝试通过将视图模型中表达的对象位置绑定到项视图中的样式属性Canvas.LeftCanvas.Top属性来反映我的观点。然而,这些绑定似乎不起作用。
对于这个最小的示例,我简化了结构,只有一个控件Thing被样式化和模板化:
using System;
using System.Windows;
using System.Windows.Controls;

namespace LocationBinding
{
    public class Thing : Control
    {
        static Thing()
        {
            DefaultStyleKeyProperty.OverrideMetadata(typeof(Thing), new FrameworkPropertyMetadata(typeof(Thing)));
        }

        public Point Location {
            get {
                return new Point(70, 70);
            }
        }

        public double VPos {
            get {
                return 100;
            }
        }
    }
}

为了简单起见,我已经在主窗口的资源字典中声明了样式 - 一个带有画布的简单窗口(我的真实项目将其放在 Themes\Generic.xaml 中)。在它的样式中,我将绑定到控件的属性值。
<Window x:Class="LocationBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="clr-namespace:LocationBinding"
    Title="LocationBinding" Height="300" Width="300">
    <Window.Resources>
        <Style TargetType="local:Thing">
            <Setter Property="Panel.ZIndex" Value="542"/>
            <Setter Property="Canvas.Left" Value="{Binding Location.X}"/>
            <Setter Property="Canvas.Top" Value="{Binding VPos}"/>
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="local:Thing">
                        <Ellipse Fill="ForestGreen" Width="30" Height="30"/>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
        </Style>
    </Window.Resources>
    <Canvas Name="cnv">

    </Canvas>
</Window>

主窗口的代码只是在画布上添加一个“Thing”实例:
using System;
using System.Windows;

namespace LocationBinding
{
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();

            cnv.Children.Add(new Thing());
        }
    }
}

样式已经正确应用,证据是 ZIndex 值(根据 Snoop)和控件的正确基于模板的外观。然而,Canvas.LeftCanvas.Top 仍未设置(因此 Thing 粘在画布的左上角),尽管根据诸如thisthis等线程,Property="Canvas.Left" 似乎是引用样式中附加属性的正确语法。
我最初尝试将Canvas.Top绑定到Location.Y,并将其替换为 VPos 属性,以防问题与结构属性的绑定有关,但这似乎也没有改变任何东西。
我缺少什么;如何在我的样式中将Canvas.LeftCanvas.Top绑定到我的Thing.Location属性的坐标?
1个回答

4

默认情况下,绑定将在控件的DataContext中查找属性,但Location是您控件(Thing)的属性。

因此,您需要使用RelativeSource并将Mode设置为Self,以告诉绑定引擎在控件本身而不是控件的DataContext中查找属性:

<Setter Property="Canvas.Left" Value="{Binding Location.X,
                                      RelativeSource={RelativeSource Self}}"/>

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接