非常简单的问题,但似乎无法在这里找到完整的答案......
我需要在xaml中将数据绑定到codebehind中的类成员的属性。
<Window x:Class="Main">
<customcontrol Name="View" IsChecked="{Binding ElementName=RecordProp, Path=IsViewChecked}" />
...
背后的代码如下:
class Main
{
...
private Record _record;
public Record RecordProp
{
get { return _record; }
}
...
}
class Record
{
public bool IsViewChecked
{
get; set;
}
}
我现在得到的东西不起作用,我做错了什么?
答案 0 :(得分:29)
我在这里看到的是,您的窗口的类名是Main
,您已经为其添加了RecordProp
属性,并且您现在正尝试绑定到{{ 1}}名为IsChecked
的元素的属性。我觉得你对名字的运作方式有点困惑。
将RecordProp
属性添加到XAML元素会在窗口类中创建一个具有该名称的字段。这允许您在代码中引用命名元素,这可能会让您认为绑定可以做同样的事情。
但这不是绑定如何找到命名元素。 x:Name
属性也获取XAML元素创建的对象,并在窗口的namescope中以该名称注册它。 (参见MSDN's article on XAML namescopes.)这是解析元素名称的绑定。由于您没有将对象添加到namescope中,因此在绑定上设置x:Name
属性将无法找到它。
有几件事你可以想象。如果你真的想绑定到窗口的属性,你可以给窗口命名并使用属性路径绑定到属性:
ElementName
更简单的方法是在构造函数中设置数据上下文:
<Window x:Name="MainWindow" x:Class="Main">
...
<customcontrol Name="View" IsChecked="
{Binding ElementName=MainWindow,
Path=RecordProp.IsViewChecked}" />
一旦你这样做,你就可以绑定到DataContext = this;
属性(以及窗口的任何其他属性),如下所示:
RecordProp
当然,如果您需要将窗口的数据上下文设置为其他内容,那么这将无效。
另一种可能性是实现这样的属性:
<customControl Name="View" IsChecked={Binding RecordProp.IsChecked}/>
您可以使用(例如)public Record RecordProp
{
get { return (Record)Resources["RecordProp"]; }
set { Resources["RecordProp"] = value; }
}
绑定到此。由于它是一个动态资源,如果窗口外部的某些内容设置了窗口的Binding {DynamicResource RecordProp}, Path=IsChecked"
属性,则对它的绑定将刷新 - 如果你只是使RecordProp
属性,这是不会发生的事情(除非你实施变更通知)。
答案 1 :(得分:27)
Path需要一个Source来反对(Source,DataContext,RelativeSource,ElementName)。 ElementName只能用于通过x:Name引用在XAML中声明的元素。请尝试将此指向您的窗口作为源:
IsChecked="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}, Path=RecordProp.IsViewChecked}"
答案 2 :(得分:7)
我相信我的回答比到目前为止所说的要简单。只需将其添加到XAML中的窗口声明(第一个标记):
x:Name="this"
然后你可以像这样数据绑定:
<customcontrol Name="View" IsChecked="{Binding ElementName=this, Path=RecordProp.IsViewChecked}" />
我检查了C#是否抱怨已经存在“这个”,但它没有,我猜是因为它们都引用完全相同的对象。
这是我遇到同样问题时使用的解决方案,我发现使用它非常直观。
答案 3 :(得分:3)
数据绑定不适用于私有字段。它的意思是公共财产。尝试公开地公开值_record
并将其绑定到该值。