繁体   English   中英

如何将 WPF 复选框的 IsChecked 属性绑定到非窗口对象的布尔属性

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

我找到了很多关于如何将 WPF 复选框的 IsChecked 属性绑定到布尔属性的示例,如果它们都属于同一个 Window 类。 我想做不同的事情:

我有主窗口(摘录):

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

    private readonly SoundFx _soundFx = new SoundFx();

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

然后我有 SoundFx 类(摘录):

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

}

我有 XAML(摘录):

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

老实说,我是 WPF 的新手,不知道我在做什么。 我想要实现的是当用户单击checkBoxSoundFx元素时更改_soundFx.Enabled的值,而不使用任何事件处理程序,如CheckedUnchecked 这应该可以通过数据绑定来实现,不是吗?

首先你需要创建

 public SoundFx _soundFx  { get; set; }

作为公共财产,因为您不能绑定到私有字段

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

从 xaml 开始,您需要像这样绑定:

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

你很接近,你需要一个属性来绑定,如果你没有这样做,你需要设置 DataContext:

public partial class MainWindow
{
    public MainWindow()
    {
        this.DataContext = this;
        InitializeComponent();
    }

    private readonly SoundFx _soundFx = new SoundFx();
    public SoundFx {get {return _soundFx;}}

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

然后需要绑定到这个属性(如果只需要设置属性,则设置模式为OneWayToSource,不要根据属性值更新CheckBox):

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

顺便说一下,我不确定为什么您的 SoundFx 是一个 DependencyObject,为什么您的 Enabled 属性是一个 DependencyProperty。 在这个特定的例子中,一个简单的属性也可以工作。

例如,当您想将它们设置为 Style 或使用 Storyboard 为它们设置动画时,DependencyProperties 很有用,但在这种情况下似乎并非如此。 我认为 SoundFx 应该继承 DependencyObject 并且 Enabled 应该是一个简单的属性(尽管这是我对您的项目知之甚少的观点)。

与此同时,由于我在 WPF 方面的经验越来越丰富,我现在要说我的问题本身是错误的。 为了避免视图和模型之间的绑定混淆和不必要的依赖关系,我现在总是更喜欢 MVVM 来处理这种情况。

示例: https : //codereview.stackexchange.com/questions/124361/mvvm-am-i-doing-it-right

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM