我试图通过将项目视图样式中的Canvas.Left
和Canvas.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.Left
和Canvas.Top
仍然未设置(因此Thing
仍然位于画布的左上角),即使根据this或{{ 3}},Property="Canvas.Left"
似乎是引用样式中附加属性的正确语法。
我首先尝试将Canvas.Top
绑定到Location.Y
并将其替换为VPos
属性,以防问题与绑定到struct属性有关,但这似乎没有改变什么都可以。
我缺少什么;如何将我的样式中的Canvas.Left
和Canvas.Top
绑定到Thing.Location
属性的坐标?
答案 0 :(得分:3)
默认情况下,绑定将搜索控件的DataContext 中的属性,但Location
是您的控件( Thing )属性。
所以你需要使用模式设置为RelativeSource
的{{1}}来告诉绑定引擎在控件本身而不是在控件的DataContext中搜索属性:
Self