【问题标题】:WPF Databinding CheckBox.IsCheckedWPF 数据绑定 CheckBox.IsChecked
【发布时间】:2010-11-04 01:02:14
【问题描述】:

如何将 CheckBox 的 IsChecked 成员绑定到表单中的成员变量?

(我意识到我可以直接访问它,但我正在尝试了解数据绑定和 WPF)

以下是我未能成功的尝试。

XAML:

<Window x:Class="MyProject.Form1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Title" Height="386" Width="563" WindowStyle="SingleBorderWindow">
<Grid>
    <CheckBox Name="checkBoxShowPending" 
              TabIndex="2" Margin="0,12,30,0" 
              Checked="checkBoxShowPending_CheckedChanged" 
              Height="17" Width="92" 
              VerticalAlignment="Top" HorizontalAlignment="Right" 
              Content="Show Pending" IsChecked="{Binding ShowPending}">
    </CheckBox>
</Grid>
</Window>

代码:

namespace MyProject
{
    public partial class Form1 : Window
    {
        private ListViewColumnSorter lvwColumnSorter;

        public bool? ShowPending
        {
            get { return this.showPending; }
            set { this.showPending = value; }
        }

        private bool showPending = false;

        private void checkBoxShowPending_CheckedChanged(object sender, EventArgs e)
        {
            //checking showPending.Value here.  It's always false
        }
    }
}

【问题讨论】:

    标签: wpf data-binding checkbox


    【解决方案1】:
    <Window ... Name="MyWindow">
      <Grid>
        <CheckBox ... IsChecked="{Binding ElementName=MyWindow, Path=ShowPending}"/>
      </Grid>
    </Window>
    

    请注意,我为&lt;Window&gt; 添加了一个名称,并更改了 CheckBox 中的绑定。如果您希望它能够在更改时更新,您还需要将 ShowPending 实现为 DependencyProperty

    【讨论】:

    • 如果属性位于ViewModel 而不是View 本身,您将如何进行绑定?
    • 如果使用 ViewModel,您通常会将 View(或 XAML)中的 DataContext 设置为 ViewModel,然后只需执行 IsChecked="{Binding ShowPending}"
    【解决方案2】:

    @Will 回答的附录:这就是您的DependencyProperty 的样子(使用Dr. WPF's snippets 创建):

    #region ShowPending
    
    /// <summary>
    /// ShowPending Dependency Property
    /// </summary>
    public static readonly DependencyProperty ShowPendingProperty =
        DependencyProperty.Register("ShowPending", typeof(bool), typeof(MainViewModel),
            new FrameworkPropertyMetadata((bool)false));
    
    /// <summary>
    /// Gets or sets the ShowPending property. This dependency property 
    /// indicates ....
    /// </summary>
    public bool ShowPending
    {
        get { return (bool)GetValue(ShowPendingProperty); }
        set { SetValue(ShowPendingProperty, value); }
    }
    
    #endregion
    

    【讨论】:

      【解决方案3】:

      您必须将绑定模式设置为 TwoWay :

      <Checkbox IsChecked="{Binding Path=ShowPending, Mode=TwoWay}"/>
      

      【讨论】:

      • 虽然 OneWay 是许多属性的默认设置,但 IsChecked 属性默认为 TwoWay。见Binding Overview
      【解决方案4】:

      如果您只想将一个控件绑定到代码隐藏的属性,则可以通过RelativeSource 将其指定为绑定中的源,如下所示:

      <CheckBox ...
      IsChecked="{Binding ShowPending, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
      

      这可能是答案的结尾。但更一般地说,您将拥有多个控件并希望将它们绑定到您的类上的各种属性。在这种情况下,利用 DataContext 属性(这是数据绑定的默认源对象)通过控件层次结构向下继承这一事实更加简洁和方便,因此将其设置在顶层将使其可用于所有子控件。

      DataContext 没有默认值,但至少有两种方法可以将 Window 元素的 DataContext 属性设置为指向自身:

      • 通过在代码隐藏构造函数中设置DataContext = this。这非常简单,但有些人可能会争辩说,在 XAML 中并不清楚 DataContext 指向的位置。
      • 通过使用 DataBinding 在 XAML 中设置 DataContext

      在 XAML 中的 Window/UserControl 级别设置 DataContext 的最简单且我认为最优雅的方法非常简单;只需将 DataContext="{Binding RelativeSource={RelativeSource Self}}" 添加到您的 Window 元素。 RelativeSource Self 仅表示“直接绑定到对象”,在本例中为 Window 对象。缺少Path 属性会导致默认Path,即源对象本身(即窗口)。

      <Window x:Class="MyProject.Form1"
          xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
          xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
          DataContext="{Binding RelativeSource={RelativeSource Self}}">
          <Grid>
              <CheckBox ... 
                  IsChecked="{Binding ShowPending}">
              </CheckBox>
          </Grid>
      </Window>
      

      完成此操作后,所有子控件的 DataContext 属性将成为 Window 类,因此数据绑定到代码隐藏中的属性将很自然。

      如果出于某种原因您不想在 Window 上设置 DataContext,但希望将其设置在控件层次结构的较低位置,那么您可以使用 FindAncestor 机制来实现。例如。如果你想在 Grid 元素和 Grid 的所有子元素上设置它:

      <Grid DataContext="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}">
          <CheckBox ...
                IsChecked="{Binding ShowPending}">
          </CheckBox>
      </Grid>
      

      在这一点上可能值得注意的是,到目前为止,我们已经实现了将 UI 控件绑定到代码隐藏类的属性的能力,并使该代码隐藏属性保持最新对 UI 元素进行更改。因此,如果用户选中 CheckBox,ShowPending 属性将被更新。

      但很多时候你也希望反过来是真的;对源属性的更改应反映在 UI 控件的相应更改中。您可以通过向窗口添加另一个 CheckBox 控件来查看这一点,该控件绑定到相同的 ShowPending 属性。当您单击一个复选框时,您可能希望或期望另一个复选框被同步,但它不会发生。要实现这一点,您的代码隐藏类应该 (a) 实现 INotifyPropertyChanged,(b) 添加 ShowPendingChanged 事件或 (c) 使 ShowPending 成为 Dependency Property。在这 3 个中,我建议在您的代码隐藏上实现 INotifyPropertryChanged 是最常见的机制。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2017-01-10
        • 1970-01-01
        • 1970-01-01
        • 2010-10-30
        • 2015-05-24
        相关资源
        最近更新 更多