首页 > 解决方案 > 复选框检查事件不会被触发

问题描述

我被这个困住了。我在 WPF 中有一个带有复选框的按钮。

模板中的按钮:

<Button Name="deleteButton" Style="{StaticResource RoundCornerButtonWithCheck}" Content="{Binding Source={x:Static localization:Resources.Delete}, Converter={StaticResource CharacterCasingConverter}}" VerticalAlignment="Center" HorizontalAlignment="Left" Background="Red" Foreground="White" Margin="80,0,80,30" Click="DeleteClick"></Button>

由于复选框是在样式中声明的,为了获得对该复选框的引用,我从代码隐藏中执行:

FrameworkElement templatedControl = this.deleteButton.Template.LoadContent() as FrameworkElement;
CheckBox templatedCheck = templatedControl.FindName("checkbox") as CheckBox;

click然后,我在代码隐藏中实现了事件的方法:

public void DeleteClick(object sender, RoutedEventArgs e)
    {
        if (!(e.OriginalSource is CheckBox))
        {
                bool isChecked = templatedCheck.IsChecked.HasValue && templatedCheck.IsChecked.Value == true;
                Debug.Print(isChecked);    // This always returns false
        }
    }

但我总是得到false价值。

我还尝试RoutedEventHandler在构造函数中添加一个:

templatedCheck.Checked += new RoutedEventHandler(this.OnCheckChanged);
templatedCheck.Unchecked += new RoutedEventHandler(this.OnCheckChanged);

然后定义处理程序。但没有效果,当我选中复选框时,不会调用这些方法。

我的想法是,这与复选框在按钮内部有关,就像从复选框发射检查事件时,它被按钮捕获,并且不会到达我的代码。无论如何,这是我的假设,但不能想知道解决方案。

复选框的样式:

<Style x:Key="FilledCheckBox" TargetType="{x:Type CheckBox}">
<Setter Property="Foreground" Value="Gray"/>
<Setter Property="Template">
    <Setter.Value>
        <ControlTemplate TargetType="{x:Type CheckBox}"> 
            <BulletDecorator Background="Transparent">
                <BulletDecorator.Bullet>
                    <Border x:Name="Border"
                            Width="15"
                            Height="15"
                            CornerRadius="1"
                            BorderThickness="1">
                        <Border.BorderBrush>
                            <SolidColorBrush Color="Gray"/>
                        </Border.BorderBrush>
                        <Border.Background>
                            <SolidColorBrush Color="White"/>
                        </Border.Background>
                    </Border>
                </BulletDecorator.Bullet>
                <ContentPresenter Margin="5,0,0,0"
                                  VerticalAlignment="Top"
                                  HorizontalAlignment="Left"
                                  RecognizesAccessKey="True" />
            </BulletDecorator>
            <ControlTemplate.Triggers>
                <Trigger Property="IsChecked" Value="True">
                    <Setter Property="Background" TargetName="Border" Value="Green"/>
                    <Setter Property="BorderBrush" TargetName="Border" Value="Green"/>
                    <Setter Property="Foreground" Value="Green"/>
                </Trigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
    </Setter.Value>
</Setter>

按钮的样式(内部带有复选框):

<Style x:Key="RoundCornerButtonWithCheck" TargetType="{x:Type Button}">
        <Setter Property="HorizontalContentAlignment" Value="Center"/>
        <Setter Property="VerticalContentAlignment" Value="Center"/>
        <Setter Property="Width" Value="120"/>
        <Setter Property="Height" Value="30"/>
        <Setter Property="Padding" Value="1"/>
        <Setter Property="Button.Effect">
            <Setter.Value>
                <DropShadowEffect Color="Black" Direction="280" ShadowDepth="2" BlurRadius="5" Opacity="0.2" />
            </Setter.Value>
        </Setter>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Grid x:Name="grid">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="120"/>
                            <ColumnDefinition Width="*"/>
                        </Grid.ColumnDefinitions>
                        <Border x:Name="border" CornerRadius="15" BorderBrush="Black" BorderThickness="0"  Background="{TemplateBinding Background}">
                            <ContentPresenter HorizontalAlignment="Center"
                                              VerticalAlignment="Center"
                                              TextElement.FontWeight="SemiBold">
                            </ContentPresenter>
                        </Border>

                        <CheckBox x:Name="checkbox" Grid.Column="0" VerticalAlignment="Center" Margin="20,0,0,0" Style="{StaticResource FilledCheckBox}"></CheckBox>
                    </Grid>
                    <ControlTemplate.Triggers>
                        <Trigger Property="IsPressed" Value="True">
                            <Setter Property="Background" TargetName="border">
                                <Setter.Value>
                                    <SolidColorBrush Color="Gold" />
                                </Setter.Value>
                            </Setter>
                        </Trigger>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter Property="BorderBrush" TargetName="border" Value="#FF33962B"/>
                        </Trigger>
                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" TargetName="grid" Value="0.25"/>
                        </Trigger>

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

标签: c#wpfxaml

解决方案


这应该有效:

private void SaveClick(object sender, RoutedEventArgs e)
{
    if (!(e.OriginalSource is CheckBox))
    {
        Button button = (Button)sender;
        CheckBox templatedCheck = button.Template.FindName("checkbox", button) as CheckBox;
        if (templatedCheck != null)
            Debug.Print(templatedCheck.IsChecked.ToString());
    }
}

它获取对实际单击CheckBox的模板中的的引用,并且该引用Button被选中或未选中。

DataTemplate.LoadContent()根据模板创建另一个Button不是您想要的元素。


推荐阅读