[ACCEPTED]-WPF Databinding CheckBox.IsChecked-checkbox

Accepted answer
Score: 12
<Window ... Name="MyWindow">
  <Grid>
    <CheckBox ... IsChecked="{Binding ElementName=MyWindow, Path=ShowPending}"/>
  </Grid>
</Window>

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

Score: 2

Addendum to @Will's answer: this is what 1 your DependencyProperty might look like (created using 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
Score: 0

You must make your binding mode as TwoWay 1 :

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

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

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

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

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

  • By setting DataContext = this in 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 DataContext in XAML using DataBinding

The simplest 37 and, I think, most elegant way to set the 36 DataContext at the Window/UserControl level 35 in XAML is very straight forward; just add 34 DataContext="{Binding RelativeSource={RelativeSource Self}}" to your Window element. RelativeSource Self just means "bind 33 directly to the object", which in this 32 case is the Window object. The lack of a Path property 31 results in the default Path, which is the source 30 object itself (i.e. the 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 29 have done this, the DataContext property for all child 28 controls will be the Window class, so data binding 27 to properties in your code-behind will be 26 natural.

If for some reason you don't want 25 to set the DataContext on the Window, but wish to set 24 it lower down the control hierarchy, then 23 you can do so by using the FindAncestor mechanism. E.g. if 22 you want to set it on the Grid element and 21 all children of the Grid:

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

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

But quite often you also 13 want the reverse to be true; a change to 12 the source property should be reflected 11 in a corresponding change to the UI Control. You 10 can see this by adding another CheckBox 9 control to your window, bound to the same 8 ShowPending property. When you click one checkbox, you 7 would probably hope or expect the other 6 Checkbox to be synchronized, but it won't 5 happen. To achieve this your code-behind 4 class should either (a) implement INotifyPropertyChanged, (b) add 3 a ShowPendingChanged event or (c) make ShowPending a Dependency Property. Of the 3, I suggest 2 implementing INotifyPropertryChanged on your code-behind is the 1 most common mechanism.

More Related questions