Search code examples
c#wpfxamlcheckboxdata-binding

How can I bind a WPF checkbox's IsChecked property to a boolean property of an object that is not a window


I found a lot of examples on how to bind the IsChecked property of a WPF checkbox to a boolean property, if both belong to the same Window class. I want to do a different thing:

I have the main window (excerpt):

public partial class MainWindow
{
    public MainWindow()
    {
        InitializeComponent();
    }

    private readonly SoundFx _soundFx = new SoundFx();

    private void _StartNewGame()
    {
        _soundFx.GameStarted();
    }
}

Then I have the SoundFx class (excerpt):

public class SoundFx : DependencyObject
{
    public void GameStarted()
    {
        if (Enabled)
        {
            _PlayGameStartedSound();
        }
    }

    public bool Enabled
    {
        get { return (bool) GetValue(EnabledProperty); }
        set { SetValue(EnabledProperty, value); }
    }
    public static readonly DependencyProperty EnabledProperty =
        DependencyProperty.Register("Enabled", typeof(bool),
            typeof(SoundFx), new UIPropertyMetadata(false));

}

And I have the XAML (excerpt):

<Grid>
    <CheckBox IsChecked="{Binding ElementName=_soundFx, Path=Enabled}" x:Name="checkBoxSoundFx" Content="Sound FX" HorizontalAlignment="Right" Margin="0,0,10,10" VerticalAlignment="Bottom"/>
</Grid>

To be honest, I'm new to WPF and don't know exactly what I'm doing. What I'm trying to achieve is that the value of _soundFx.Enabled be changed when the user clicks on the checkBoxSoundFx element, without using any event handlers like Checked or Unchecked. This should be possible with data binding, shouldn't it?


Solution

  • First you need to create

     public SoundFx _soundFx  { get; set; }
    

    as public property, because you cannot bind to private field

    public MainWindow()
    {
       InitializeComponent();
       _soundFx  = new SoundFx();
    }
    

    And from xaml you need to bind like:

    <CheckBox IsChecked=
        "{Binding RelativeSource=
           {RelativeSource Mode=FindAncestor,AncestorType=Window},
           Path=_soundFx.Enabled}"}"
        x:Name="checkBoxSoundFx" 
        Content="Sound FX" 
        HorizontalAlignment="Right" 
        Margin="0,0,10,10" 
        VerticalAlignment="Bottom"/>