WPF 绑定到代码后面的类成员
Posted
技术标签:
【中文标题】WPF 绑定到代码后面的类成员【英文标题】:WPF Bind to class member in code behind 【发布时间】:2011-01-22 22:37:07 【问题描述】:很简单的问题,但似乎无法在这里找到完整的答案...
我需要将 xaml 中的数据绑定到代码隐藏中类成员的属性。
<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;
我现在得到的东西不起作用,我做错了什么?
【问题讨论】:
【参考方案1】:数据绑定不适用于私有字段。它适用于公共财产。尝试公开公开值 _record
并改为绑定到该值。
参考 - http://msdn.microsoft.com/en-us/library/ms743643.aspx
【讨论】:
公共属性没有影响。 @user258651 我认为您还需要更新绑定上下文,以便主窗口将其默认返回到主类。不过,我已经有一段时间没有看了。【参考方案2】:Path 需要一个 Source 来反对(Source、DataContext、RelativeSource、ElementName)。 ElementName 只能用于引用在 XAML 中通过其 x:Name 声明的元素。试试这个,而不是指向你的窗口作为源:
IsChecked="Binding RelativeSource=RelativeSource Mode=FindAncestor, AncestorType=x:Type Window, Path=RecordProp.IsViewChecked"
【讨论】:
【参考方案3】:我在这里看到的是你的窗口的类名是Main
,你已经向它添加了一个RecordProp
属性,并且你现在正试图绑定到IsChecked
属性名为 RecordProp
的元素。我认为您对名称的工作方式有些困惑。
将x:Name
属性添加到 XAML 元素会在窗口类中使用该名称创建一个字段。这允许您在代码中引用命名元素,并且可能让您认为绑定可以做同样的事情。
但这不是绑定找到命名元素的方式。 x:Name
属性 also 采用 XAML 元素创建的对象,并在窗口的名称范围内以该名称注册它。 (参见MSDN's article on XAML namescopes.)这就是绑定用来解析元素名称的方法。由于您从未将对象添加到名称范围,因此无法在绑定上设置 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
属性,它的绑定将会刷新——如果你只是将RecordProp
设置为一个属性就不会发生这种情况(除非你实现更改通知)。
【讨论】:
请注意,DataContext 不应在 Window 构造函数中设置,而应在 Loaded 事件处理程序中设置。当我在 Loaded 事件中填充 ObservableCollection 时,在构造函数中设置它对我不起作用。 无需从代码中设置Windows
的DataContext
,您只需将其添加到Windows
的XAML:DataContext="Binding RelativeSource=RelativeSource Self
【参考方案4】:
我相信我有一个比目前所说的更简单的答案。只需将其添加到 XAML 中的窗口声明(第一个标记):
x:Name="this"
然后你可以像这样进行数据绑定:
<customcontrol Name="View" IsChecked="Binding ElementName=this, Path=RecordProp.IsViewChecked" />
我检查了 C# 是否抱怨已经有一个“this”,但它没有,我猜是因为它们都引用了完全相同的对象。
这是我遇到同样问题时使用的解决方案,我发现它使用起来非常直观。
【讨论】:
有理由不这样做吗?我尝试了其他解决方案但没有成功。这是我能够使用我的菜鸟 C# 技能使其工作的唯一方法。 如果您投反对票,请评论为什么您认为这是一个糟糕的解决方案。以上是关于WPF 绑定到代码后面的类成员的主要内容,如果未能解决你的问题,请参考以下文章