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

WPF自定义控件中如何将ToggleButton事件绑定到传入的ICommand?

WPF自定义控件命令绑定问题

我为应用创建了一个WPF自定义控件WindowHeader,目前需要给控件内的ToggleButton关联事件逻辑。已在WindowHeader.cs中定义了TargetSelectedCommand依赖属性,在WindowHeader.xaml的控件模板里,ToggleButton绑定了PreviewMouseDown等事件,希望在Target_PreviewMouseDown触发时,执行通过WindowHeader传入的TargetSelectedCommand命令。相关代码如下:


WindowHeader.cs

public class WindowHeader : ContentControl 
{
    public static readonly DependencyProperty TargetSelectedCommandProperty = 
        DependencyProperty.Register(nameof(TargetSelectedCommand), typeof(ICommand), typeof(WindowHeader));   

    public ICommand TargetSelectedCommand
    {
        get => (ICommand)GetValue(TargetSelectedCommandProperty);
        set => SetValue(TargetSelectedCommandProperty, value);
    }
}

WindowHeader.xaml

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    xmlns:ctrl="clr-namespace:App.Windows.Lib.CustomControls"
                    x:Class="App.Windows.Lib.Style.CustomControls.WindowHeader"
                    x:ClassModifier="public">

  <Style TargetType="{x:Type ctrl:WindowHeader}">

    <Setter Property="Template">

      <Setter.Value>

        <ControlTemplate TargetType="{x:Type ctrl:WindowHeader}">

          <ctrl:DragArea>

          <Grid>
            <Grid.ColumnDefinitions>
              <ColumnDefinition Width="*" />
              <ColumnDefinition Width="Auto" />
            </Grid.ColumnDefinitions>

          <TextBlock Grid.Column="0"
                     Style="{DynamicResource TargetSelection_TextBlock}"
                     Text="{TemplateBinding SelectedTargetName}"
                     Visibility="{TemplateBinding ShowTargeting}"/>

            <StackPanel Grid.Column="1"
                        Style="{DynamicResource WindowHeader_StackPanel}">

                <ToggleButton PreviewMouseDown="Target_PreviewMouseDown" 
                              PreviewMouseUp="Target_PreviewMouseUp"
                              Style="{DynamicResource Target_Button}"
                              Visibility="{TemplateBinding ShowTargeting }" />

                <ToggleButton Click="Pin_Click"
                              Style="{DynamicResource Pin_Button}"
                              Visibility="{TemplateBinding ShowPinning}" />

               <ToggleButton Click="Resize_Click"
                             Style="{DynamicResource Resize_Button}"
                             Visibility="{TemplateBinding ShowResizing}"/>
              
            </StackPanel>

          </Grid>

          </ctrl:DragArea>

        </ControlTemplate>
        
      </Setter.Value>
      
    </Setter>
    
  </Style>
</ResourceDictionary>

WindowHeader.xaml.cs

public partial class WindowHeader : ResourceDictionary 
{
    public WindowHeader() 
    { 
        InitializeComponent(); 
    } 
        
    public void Target_PreviewMouseDown(object sender, MouseButtonEventArgs e)
    {
        // 此处需要获取传入WindowHeader的TargetSelectedCommand并执行
        throw new NotImplementedException();
    }
    
    public void Target_PreviewMouseUp(object sender, MouseButtonEventArgs e)
    {
        throw new NotImplementedException();
    }
}

MainWindow.xaml控件声明

<ctrl:WindowHeader TargetSelectedCommand="{Binding OutputDestinationViewModel.DestinationSelectedCommand}" />

解决方案

方法一:通过TemplatedParent获取控件实例执行命令

在事件处理方法中,通过ToggleButton的TemplatedParent找到对应的WindowHeader实例,进而获取并执行命令:

public void Target_PreviewMouseDown(object sender, MouseButtonEventArgs e)
{
    var toggleButton = sender as ToggleButton;
    if (toggleButton == null) return;

    // 获取模板关联的WindowHeader控件实例
    var windowHeader = toggleButton.TemplatedParent as WindowHeader;
    if (windowHeader?.TargetSelectedCommand != null && windowHeader.TargetSelectedCommand.CanExecute(null))
    {
        // 如需传递参数,将null替换为对应参数即可
        windowHeader.TargetSelectedCommand.Execute(null);
    }
}

方法二:直接在XAML中绑定Command(更符合MVVM)

如果不需要额外的鼠标事件逻辑,可以直接在ToggleButton上绑定命令,省去事件中转步骤:

<ToggleButton Command="{TemplateBinding TargetSelectedCommand}"
              Style="{DynamicResource Target_Button}"
              Visibility="{TemplateBinding ShowTargeting }" />

注意事项

  • 确保TargetSelectedCommand的CanExecute逻辑正确,执行命令前先判断是否可执行。
  • 控件模板的TargetType必须正确设置为ctrl:WindowHeader,否则TemplateBinding无法解析依赖属性。

内容的提问来源于stack exchange,提问作者Richard Gale

相关产品推荐
方舟 Agent Plan

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

最近更新时间:2026.07.11 18:15:11