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 时,在构造函数中设置它对我不起作用。 无需从代码中设置WindowsDataContext,您只需将其添加到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 绑定到代码后面的类成员的主要内容,如果未能解决你的问题,请参考以下文章

WPF 如何动态绑定static成员变量 并实现INOTIFYPROPERTYCHANGED方法

对象的继承访问控制

C++中的类所占内存空间总结

无法在成员函数中绑定右值引用参数

C11简洁之道:函数绑定

WPF 数据绑定 CheckBox.IsChecked