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