自定义wpf复选框单击事件未触发

时间:2014-09-11 23:05:59

标签: c# wpf checkbox

当然我错过了一些简单但我已经覆盖了一个复选框作为用户控件,所以我可以使用不同的图像作为其子弹装饰器。似乎工作正常,但没有响应任何点击或检查事件。我需要它在点击evnt时显示绑定的弹出窗口,但不会更改子弹装饰器图像。

此外我的绑定似乎被打破,因为当点击甚至触发(一旦它工作)它应该呈现带有绑定数据的弹出窗口。 WarningList是我要绑定的数据,在调试时它显示正确填充,只是没有正确绑定我相信

    <UserControl x:Class="Dev.App.Views.Controls.StatusResultCheckBox"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:converters="clr-namespace:Dev.App.Views.Converters"
             x:Name="Root"
             d:DesignHeight="50"
             d:DesignWidth="50"
             mc:Ignorable="d">
    <UserControl.Resources>
        <converters:WarningListFilterByOperationTypeConverter x:Key="WarningListFilterByOperationTypeConverter" />
        <DataTemplate x:Key="StatusResultNone">
            <Viewbox Width="20" Height="20">
                <Grid/>
            </Viewbox>
        </DataTemplate>
        <DataTemplate x:Key="StatusResultWarning">
            <BulletDecorator Background="Transparent">
                <BulletDecorator.Bullet>
                    <Viewbox Width="20" Height="20">
                        <Grid>
                            <Path Data="F1M874.094,289.369L854.3,254.63C854.028,254.151 853.515,253.856 852.958,253.856 852.403,253.856 851.89,254.151 851.617,254.63L831.824,289.369C831.555,289.84 831.559,290.416 831.835,290.883 832.111,291.348 832.618,291.634 833.165,291.634L872.752,291.634C873.299,291.634 873.805,291.348 874.081,290.883 874.357,290.416 874.361,289.84 874.094,289.369z"
                              Stretch="Uniform" Fill="#FFFCCE00" Width="20" Height="20" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5">
                            </Path>
                            <Path Data="M855.653,287.189L850.264,287.189 850.264,282.745 855.653,282.745 855.653,287.189z M855.653,279.41L850.264,279.41 850.264,266.077 855.653,266.077 855.653,279.41z"
                              Stretch="Uniform" Fill="Black" Width="3" Height="10" Margin="0.5,3,0,0" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5">
                            </Path>
                        </Grid>
                    </Viewbox>
                </BulletDecorator.Bullet>
                <Popup Name="WarningMessagePopup"
                               Width="{Binding ElementName=ListBox, Path=ActualWidth}"
                               Height="200"
                               HorizontalAlignment="Center"
                               HorizontalOffset="50"
                               PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
                               IsOpen="{Binding Path=IsChecked}"
                               StaysOpen="False"
                               VerticalOffset="10">
                    <TextBox VerticalScrollBarVisibility="Auto">
                        <TextBox.Text>
                            <MultiBinding Converter="{StaticResource WarningListFilterByOperationTypeConverter}" Mode="OneWay">
                                <Binding Path="OperationType" />
                                <Binding Path="DataContext.WarningList" RelativeSource="{RelativeSource AncestorType=ListBox}" />
                            </MultiBinding>
                        </TextBox.Text>
                    </TextBox>
                </Popup>
            </BulletDecorator>
        </DataTemplate>
    <ControlTemplate x:Key="CheckBoxTemplate" TargetType="ContentControl">
            <ContentControl Name="Content" />
            <ControlTemplate.Triggers>
                <DataTrigger Binding="{Binding StatusResultCheckMode, ElementName=Root}" Value="None">
                    <Setter TargetName="Content" Property="ContentTemplate" Value="{StaticResource StatusResultNone}" />
                </DataTrigger>
                <DataTrigger Binding="{Binding StatusResultCheckMode, ElementName=Root}" Value="Warning">
                    <Setter TargetName="Content" Property="ContentTemplate" Value="{StaticResource StatusResultWarning}" />
                    <Setter Property="Cursor" Value="Hand" />
                </DataTrigger>
                <DataTrigger Binding="{Binding HasStatus, ElementName=Root}" Value="True">
                    <Setter Property="Visibility" Value="Visible" />
                </DataTrigger>
            </ControlTemplate.Triggers>
        </ControlTemplate>
<Style x:Key="StatusResultVisibilityStyle" TargetType="CheckBox">
            <Setter Property="OverridesDefaultStyle" Value="true" />
            <Setter Property="Template">
                <Setter.Value>
                    <ControlTemplate TargetType="{x:Type CheckBox}">
                        <BulletDecorator Background="Transparent">
                            <BulletDecorator.Bullet>
                                <Viewbox Width="20" Height="20">
                                    <Grid />    
                                </Viewbox>
                            </BulletDecorator.Bullet>
                        </BulletDecorator>
                    </ControlTemplate>
                </Setter.Value>
            </Setter>
            <Style.Triggers>
                <MultiDataTrigger>
                    <MultiDataTrigger.Conditions>
                        <Condition Binding="{Binding IsInStatusNone.Value}" Value="False" />
                        <Condition Binding="{Binding IsInStatusWarning.Value}" Value="True" />
                    </MultiDataTrigger.Conditions>
                    <Setter Property="Visibility" Value="Visible" />
                </MultiDataTrigger>
            </Style.Triggers>
        </Style>
    </UserControl.Resources>
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="50" />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <CheckBox HorizontalAlignment="Center"
                     VerticalAlignment="Center"
                     IsChecked="True"
                     Style="{StaticResource StatusResultVisibilityStyle}"/>
        <ContentControl Grid.Column="0"
                        HorizontalAlignment="Center"
                        VerticalAlignment="Center"
                        Width="20" Height="20"
                        Template="{StaticResource CheckBoxTemplate}" />
    </Grid>
</UserControl>

从我的主页调用如下。 (嵌套在列表框中)

<controls:StatusResultCheckBox Grid.Column="3"
    IsInStatusWarning="{Binding Path=IsInStatusWarning.Value}"
    IsInStatusNone="{Binding Path=IsInStatusNone.Value}"
    HasStatus="{Binding Path=HasStatus.Value}"
    IsRunning="{Binding RelativeSource={RelativeSource AncestorType=ListBox}, Path=DataContext.IsRunning.Value}"/>

用户控件背后的代码......

using System.Windows;
using System.Windows.Controls;

namespace Dev.App.Views.Controls
{
    /// <summary>
    /// Interaction logic for StatusResultCheckBox.xaml
    /// </summary>
    public partial class StatusResultCheckBox : UserControl
    {
        public static readonly DependencyProperty StatusResultCheckModeProperty =
            DependencyProperty.Register("StatusResultCheckMode", typeof(StatusResultCheckMode), typeof(StatusResultCheckBox), new PropertyMetadata(StatusResultCheckMode.None));

        public static readonly DependencyProperty IsRunningProperty =
           DependencyProperty.Register("IsRunning", typeof(bool), typeof(StatusResultCheckBox), new PropertyMetadata(false, IsRunningPropertyChanged));

        public static readonly DependencyProperty HasStatusProperty =
           DependencyProperty.Register("HasStatus", typeof(bool), typeof(StatusResultCheckBox), new PropertyMetadata(false, IsRunningPropertyChanged));

        public static readonly DependencyProperty IsInStatusWarningProperty =
           DependencyProperty.Register("IsInStatusWarning", typeof(bool), typeof(StatusResultCheckBox), new PropertyMetadata(false, IsRunningPropertyChanged));

        public static readonly DependencyProperty IsInStatusNoneProperty =
           DependencyProperty.Register("IsInStatusNone", typeof(bool), typeof(StatusResultCheckBox), new PropertyMetadata(false, IsRunningPropertyChanged));

        private static void IsRunningPropertyChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var statusResultCheckBox = d as StatusResultCheckBox;

            if (statusResultCheckBox != null)
            {
                if (statusResultCheckBox.IsRunning)
                {
                    if (statusResultCheckBox.IsInStatusWarning)
                    {
                        statusResultCheckBox.StatusResultCheckMode = StatusResultCheckMode.Warning;
                        statusResultCheckBox.HasStatus = true;
                    }
                    else
                    {
                        statusResultCheckBox.StatusResultCheckMode = StatusResultCheckMode.None;
                        statusResultCheckBox.HasStatus = false;
                    }
                }
            }
        }

        public StatusResultCheckBox()
        {
            InitializeComponent();
        }

        public StatusResultCheckMode StatusResultCheckMode
        {
            get { return (StatusResultCheckMode)GetValue(StatusResultCheckModeProperty); }
            set { SetValue(StatusResultCheckModeProperty, value); }
        }

        public bool IsRunning
        {
            get { return (bool)GetValue(IsRunningProperty); }
            set { SetValue(IsRunningProperty, value); }
        }

        public bool HasStatus
        {
            get { return (bool)GetValue(HasStatusProperty); }
            set { SetValue(HasStatusProperty, value); }
        }

        public bool IsInStatusWarning
        {
            get { return (bool)GetValue(IsInStatusWarningProperty); }
            set { SetValue(IsInStatusWarningProperty, value); }
        }

        public bool IsInStatusNone
        {
            get { return (bool)GetValue(IsInStatusNoneProperty); }
            set { SetValue(IsInStatusNoneProperty, value); }
        }
    }

    public enum StatusResultCheckMode
    {
        None,
        Warning
    }
}

2 个答案:

答案 0 :(得分:0)

如果您想要执行此类操作,只需将样式应用于现有复选框即可。

您可以从here获取默认样式并更改所需内容。

答案 1 :(得分:0)

结束重构所有这些代码并简化。基本上是一个togglebutton风格。

<ToggleButton Grid.Column="3" Style="{StaticResource WarningStyle}"/>

在资源文件中......

<Style x:Key="WarningStyle" TargetType="ToggleButton">
    <Setter Property="VerticalAlignment" Value="Center" />
    <Setter Property="HorizontalAlignment" Value="Center" />
    <Setter Property="HorizontalContentAlignment" Value="Center" />
    <Setter Property="Cursor" Value="Hand" />
    <Setter Property="Background" Value="Transparent" />
    <Setter Property="Visibility" Value="Collapsed" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ToggleButton">
                <Grid>
                    <Path Data="F1M874.094,289.369L854.3,254.63C854.028,254.151 853.515,253.856 852.958,253.856 852.403,253.856 851.89,254.151 851.617,254.63L831.824,289.369C831.555,289.84 831.559,290.416 831.835,290.883 832.111,291.348 832.618,291.634 833.165,291.634L872.752,291.634C873.299,291.634 873.805,291.348 874.081,290.883 874.357,290.416 874.361,289.84 874.094,289.369z"
                          Stretch="Uniform" Fill="#FFFCCE00" Width="20" Height="20" Margin="0,0,0,0" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5">
                    </Path>
                    <Path Data="M855.653,287.189L850.264,287.189 850.264,282.745 855.653,282.745 855.653,287.189z M855.653,279.41L850.264,279.41 850.264,266.077 855.653,266.077 855.653,279.41z"
                          Stretch="Uniform" Fill="Black" Width="3" Height="10" Margin="0.5,3,0,0" RenderTransformOrigin="0.5,0.5" StrokeThickness="0.5">
                    </Path>
                    <Popup Name="WarningMessagePopup"
                           Width="425"
                           Height="150"
                           HorizontalAlignment="Center"
                           HorizontalOffset="22"
                           PlacementTarget="{Binding RelativeSource={RelativeSource TemplatedParent}}"
                           IsOpen="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=IsChecked}"
                           StaysOpen="False"
                           VerticalOffset="7">
                        <ListBox ItemsSource="{Binding Path=WarningList}">
                            <ListBox.Style>
                                <Style TargetType="{x:Type ListBox}">
                                    <Style.Triggers>
                                        <Trigger Property="IsVisible" Value="True">
                                            <Setter Property="Background" Value="#F8FCFF"/>
                                        </Trigger>
                                    </Style.Triggers>
                                </Style>
                            </ListBox.Style>
                            <ListBox.ItemTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <TextBlock>
                                            <TextBlock.Text>
                                                <MultiBinding Converter="{StaticResource WarningListFilterByOperationTypeConverter}" Mode="OneWay">
                                                    <Binding Path="Count" />
                                                    <Binding Path="Message" />
                                                </MultiBinding>
                                            </TextBlock.Text>
                                        </TextBlock>
                                    </StackPanel>
                                </DataTemplate>
                            </ListBox.ItemTemplate>
                        </ListBox>
                    </Popup>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
    <Style.Triggers>
        <DataTrigger Binding="{Binding IsInStatusWarning.Value}" Value="True" >
            <Setter Property="Visibility" Value="Visible" />
        </DataTrigger>
    </Style.Triggers>
</Style>