WPF 数据绑定 CheckBox.IsChecked

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/1013358/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-08 20:35:20  来源:igfitidea点击:

WPF Databinding CheckBox.IsChecked

wpfdata-bindingcheckbox

提问by Adam Tegen

How would I bind the IsChecked member of a CheckBox to a member variable in my form?

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

(I realize I can access it directly, but I am trying to learn about databinding and WPF)

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

Below is my failed attempt to get this working.

以下是我尝试使此工作失败的尝试。

XAML:

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>

Code:

代码:

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
        }
    }
}

回答by Will Eddins

<Window ... Name="MyWindow">
  <Grid>
    <CheckBox ... IsChecked="{Binding ElementName=MyWindow, Path=ShowPending}"/>
  </Grid>
</Window>

Note i added a name to <Window>, and changed the binding in your CheckBox. You will need to implement ShowPending as a DependencyPropertyas well if you want it to be able to update when changed.

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

回答by Pat

Addendum to @Will's answer: this is what your DependencyPropertymight look like (created using Dr. WPF's snippets):

@Will 回答的附录:这就是你的DependencyProperty样子(使用Dr. WPF 的片段创建):

#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

回答by itzmebibin

You must make your binding mode as TwoWay :

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

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

回答by Rob

If you have only one control that you want to bind to a property of your code-behind, then you can specify this as the source in your binding via a RelativeSourcelike this:

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

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


That could be the end of the answer. But more generally you will have multiple controls and wish to bind them to various properties on your class. In this case it is neater and more convenient to make use of the fact that the DataContextproperty (which is the default source object for data binding) is inherited down through the control hierarchy, so setting it at the top level will make it available to all the child controls.

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

There is no default value for DataContext, but there are at least two ways you can set the DataContextproperty of your Window element to point at itself:

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

  • By setting DataContext = thisin the code-behind constructor. This is very simple, but some might argue that it's not clear in the XAML where the DataContext is pointing.
  • By setting the DataContextin XAML using DataBinding
  • 通过DataContext = this在代码隐藏构造函数中设置。这很简单,但有些人可能会争辩说,在 XAML 中 DataContext 指向的位置并不明确。
  • 通过DataContext使用 DataBinding 在 XAML 中设置

The simplest and, I think, most elegant way to set the DataContext at the Window/UserControl level in XAML is very straight forward; just add DataContext="{Binding RelativeSource={RelativeSource Self}}"to your Windowelement. RelativeSource Selfjust means "bind directly to the object", which in this case is the Windowobject. The lack of a Pathproperty results in the default Path, which is the source object itself (i.e. the Window).

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

<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>

Once you have done this, the DataContextproperty for all child controls will be the Windowclass, so data binding to properties in your code-behind will be natural.

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

If for some reason you don't want to set the DataContexton the Window, but wish to set it lower down the control hierarchy, then you can do so by using the FindAncestormechanism. E.g. if you want to set it on the Grid element and all children of the Grid:

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

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

It's probably worth noting at this point that what we have achieved so far is the ability to bind a UI Control to a property of your code-behind class, and for that code-behind property to be kept up-to-date with changes to the UI element. So if the user checks the CheckBox, the ShowPendingproperty will be updated.

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

But quite often you also want the reverse to be true; a change to the source property should be reflected in a corresponding change to the UI Control. You can see this by adding another CheckBox control to your window, bound to the same ShowPendingproperty. When you click one checkbox, you would probably hope or expect the other Checkbox to be synchronized, but it won't happen. To achieve this your code-behind class should either (a) implement INotifyPropertyChanged, (b) add a ShowPendingChangedevent or (c) make ShowPendinga Dependency Property. Of the 3, I suggest implementing INotifyPropertryChangedon your code-behind is the most common mechanism.

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