什么会导致我的模板在此自定义控件中被忽略

本文关键字:自定义控件 我的 什么 | 更新日期: 2023-09-27 17:56:51

编辑: 原始标题: 当我添加基于计时器的自定义控件时,我的模板将被忽略。

我正在研究 Microsoft Press 的 70-511 训练套件,并将第 5 章中的两个练习组合在一起。

问题是,当我将自定义控件添加到我的 MainWindow 时,它会运行,但 Button 模板上的触发器会被忽略。 删除同一控件时,将遵循触发器。

对于那些无法访问本书并且不想分析代码的人来说,它是一个带有标签的自定义控件,该标签具有依赖项属性设置,以使用当前系统时间更新计时器对象(每秒一次)。

正如您可能从我附加的代码中推断的那样,自定义控件位于 5_3 项目引用的单独程序集中。

我对这个有点困惑。 是什么原因造成的?

这是代码:

MainWindow.xaml:

<Window x:Class="chapter5_3.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="350" Width="525" xmlns:my="clr-namespace:chapter5_3CustomControl;assembly=chapter5_4CustomControl">
<Window.Resources>
    <ControlTemplate TargetType="{x:Type Button}" x:Key="ButtonTemplate">
        <Border Name="Bord1" BorderBrush="Olive" BorderThickness="{TemplateBinding BorderThickness}">
            <Grid>
                <Rectangle Name="rect1">
                    <Rectangle.Fill>
                        <SolidColorBrush x:Name="rosyBrush" Color="RosyBrown"/>
                    </Rectangle.Fill>
                </Rectangle>
                <ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center" />
            </Grid>
        </Border>
        <ControlTemplate.Triggers>
            <Trigger Property="IsMouseOver" Value="True" >
                <Trigger.EnterActions>
                    <BeginStoryboard Name="bst2">
                        <Storyboard AutoReverse="False">
                            <ColorAnimation Duration="0:0:.3"
                                            Storyboard.TargetProperty="Color" 
                                            Storyboard.TargetName="rosyBrush" >
                                <ColorAnimation.By>
                                    <Color A="0" R="100" B="0" G="0"/>
                                </ColorAnimation.By>
                            </ColorAnimation>
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="bst2" />
                </Trigger.ExitActions>
            </Trigger>
            <Trigger Property="IsPressed" Value="True">
                <Trigger.EnterActions>
                    <BeginStoryboard Name="bst1">
                        <Storyboard>
                            <ThicknessAnimation Storyboard.TargetName="Bord1"
                 Storyboard.TargetProperty="BorderThickness"
                 By=".1" Duration="0:0:.3" />
                            <ColorAnimation AutoReverse="False" To="DarkRed" Duration="0:0:.3"
                                            Storyboard.TargetProperty="Color" 
                                            Storyboard.TargetName="rosyBrush" />
                        </Storyboard>
                    </BeginStoryboard>
                </Trigger.EnterActions>
                <Trigger.ExitActions>
                    <StopStoryboard BeginStoryboardName="bst1" />
                </Trigger.ExitActions>
            </Trigger>
            <Trigger Property="IsEnabled" Value="False">
                <Setter TargetName="rect1" Property="Fill" Value="Gray"></Setter>
            </Trigger>
        </ControlTemplate.Triggers>
    </ControlTemplate>
</Window.Resources>
<Grid>
    <Button Template="{StaticResource ResourceKey=ButtonTemplate}" Height="23" Width="100" BorderThickness="2" Name="btnHello" Content="Hello" IsEnabled="False">
    </Button>
    <ToolBarPanel>
        <CheckBox IsChecked="True" Content="Enable Button" Name="cbEnabled" Checked="cbEnabled_Checked" Unchecked="cbEnabled_Checked"/>
    </ToolBarPanel>
    <my:CustomControl1 Name="customControl11" />
</Grid>

自定义控件1.xaml:(单独的程序集)

<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:chapter5_3CustomControl">
<Style TargetType="{x:Type local:CustomControl1}">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type local:CustomControl1}">
                <Border Background="{TemplateBinding Background}"
                        BorderBrush="{TemplateBinding BorderBrush}"
                        BorderThickness="{TemplateBinding BorderThickness}">
                    <TextBlock Foreground="{TemplateBinding Foreground}" HorizontalAlignment="Center"
                                   Text="{Binding Path=Time}" />
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

自定义控制.cs

public class CustomControl1 : Control
{
    public static readonly DependencyProperty TimeProperty;
    System.Timers.Timer myTimer = new System.Timers.Timer();
    delegate void SetterDelegate();
    static CustomControl1()
    {
        FrameworkPropertyMetadata metadata = new FrameworkPropertyMetadata();
        TimeProperty = DependencyProperty.Register("Time", typeof(string), typeof(CustomControl1), metadata);
        DefaultStyleKeyProperty.OverrideMetadata(typeof(CustomControl1), new FrameworkPropertyMetadata(typeof(CustomControl1)));
    }
    public CustomControl1()
    {
        myTimer.Elapsed += timer_elapsed;
        myTimer.Interval = 1000;
        myTimer.Start();
        this.DataContext = this;
    }
    void TimeSetter()
    {
        SetValue(TimeProperty, DateTime.Now.ToLongTimeString());
    }
    void timer_elapsed(object sender, System.Timers.ElapsedEventArgs e)
    {
        Dispatcher.Invoke(new SetterDelegate(TimeSetter), 
            System.Windows.Threading.DispatcherPriority.Normal);
    }
}

编辑:

我想插入一个我使用的免费工具,叫做 snoop! 你可以在这里找到它,我推荐它,因为它允许你在运行时检查你的控件!史努比在编辑时住在这里: http://snoopwpf.codeplex.com/它为我节省了很多时间!

什么会导致我的模板在此自定义控件中被忽略

由于按钮和自定义控件位于网格的同一行和同一列中,因此自定义控件可能覆盖了按钮。你可能只是看不到它。

如果将自定义控件的背景设置为红色,则您将看到它覆盖的区域。

如果您希望 Button(如果 Button) 响应

鼠标事件,则需要确保 CustomControl 不会覆盖该按钮。或者,您可以在自定义控件上将IsHitTestVisible设置为false,或者确保其背景为空。