You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何在WPF中暴露子控件属性?绑定自定义控件Expanded与ToggleButton的IsChecked

问题描述

我编写了一个名为MyCustomToggleButton的用户控件,该控件封装了一个ToggleButton。我希望根据此ToggleButton的IsChecked属性来显示或隐藏Grid控件。我已添加了一个名为Expanded的依赖属性(也可复用IsChecked属性),并通过ToggleButton的Checked/Unchecked事件对其进行控制。相关代码如下:

调用处XAML代码

<controls:CustomToggleButton x:Name="MyCustomToggleButton">
    <Grid Visibility="{Binding Expanded, ElementName=MyCustomToggleButton, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}" />
</controls:CustomToggleButton>

自定义控件后台代码

public static readonly DependencyProperty ExpandedProperty =
    DependencyProperty.Register(nameof(Expanded), typeof(bool), typeof(CustomToggleButton), new PropertyMetadata(false));

public bool Expanded
{
    get => (bool)GetValue(ExpandedProperty);
    set => SetValue(ExpandedProperty, value);
}

public MyCustomToggleButton()
{
    InitializeComponent();
     
    // ToggleButton是XAML中定义的内部ToggleButton控件名称
    ToggleButton.Checked += (sender, e) => Expanded = true;
    ToggleButton.Unchecked += (sender, e) => Expanded = false;
}

请问如何将自定义控件的Expanded属性与ToggleButton的IsChecked属性进行绑定?


解决方案

你可以通过以下几种方式实现属性同步,替代事件处理的方式,代码更简洁且符合WPF绑定的设计理念:

方法1:XAML内部双向绑定(推荐)

在自定义控件的XAML文件(如MyCustomToggleButton.xaml)中,直接给内部ToggleButton设置双向绑定,让IsChecked和Expanded属性自动同步:

<ToggleButton x:Name="ToggleButton" 
              IsChecked="{Binding Expanded, RelativeSource={RelativeSource AncestorType=local:MyCustomToggleButton}, Mode=TwoWay}" />
  • RelativeSource指定绑定源为自定义控件本身
  • Mode=TwoWay确保双向同步:点击ToggleButton时更新Expanded,外部修改Expanded时也会同步ToggleButton的选中状态

设置完成后,即可删除后台的Checked和Unchecked事件处理代码。

方法2:复用ToggleButton的IsChecked属性(无需额外Expanded)

如果不需要单独的Expanded属性,可以直接将内部ToggleButton的IsChecked暴露为自定义控件的依赖属性:

后台代码修改

// 复用ToggleButton的IsChecked属性作为自定义控件的依赖属性
public static readonly DependencyProperty IsCheckedProperty =
    ToggleButton.IsCheckedProperty.AddOwner(typeof(MyCustomToggleButton), new PropertyMetadata(false));

public bool? IsChecked
{
    get => (bool?)GetValue(IsCheckedProperty);
    set => SetValue(IsCheckedProperty, value);
}

自定义控件XAML绑定

<ToggleButton x:Name="ToggleButton" 
              IsChecked="{Binding IsChecked, RelativeSource={RelativeSource AncestorType=local:MyCustomToggleButton}, Mode=TwoWay}" />

调用处绑定修改

<controls:CustomToggleButton x:Name="MyCustomToggleButton">
    <Grid Visibility="{Binding IsChecked, ElementName=MyCustomToggleButton, Converter={StaticResource BooleanToVisibilityConverter}, FallbackValue=Collapsed}" />
</controls:CustomToggleButton>

方法3:依赖属性回调同步(适用于需额外逻辑的场景)

如果需要在Expanded属性变化时执行自定义逻辑,可以在依赖属性元数据中添加回调,同时处理ToggleButton的状态反向同步:

后台代码修改

public static readonly DependencyProperty ExpandedProperty =
    DependencyProperty.Register(nameof(Expanded), typeof(bool), typeof(CustomToggleButton), new PropertyMetadata(false, OnExpandedChanged));

public bool Expanded
{
    get => (bool)GetValue(ExpandedProperty);
    set => SetValue(ExpandedProperty, value);
}

private static void OnExpandedChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
    var control = (MyCustomToggleButton)d;
    // 这里可添加属性变化时的额外逻辑
    control.ToggleButton.IsChecked = (bool)e.NewValue;
}

public MyCustomToggleButton()
{
    InitializeComponent();
    // 反向同步ToggleButton的状态到Expanded
    ToggleButton.IsCheckedChanged += (sender, e) =>
    {
        if (ToggleButton.IsChecked != Expanded)
        {
            Expanded = ToggleButton.IsChecked.GetValueOrDefault(false);
        }
    };
}

内容的提问来源于stack exchange,提问作者Ludovic Wagner

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.07.03 17:07:06