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

时间:2011-05-18 04:18:06

标签: c# wpf xaml

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

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

问题在于,当我将自定义控件添加到我的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>

CustomControl1.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>

CustomControl.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的免费工具!你可以在这里找到它,我推荐它,因为它允许你在运行时检查你的控件! Snoop在编辑时住在这里:http://snoopwpf.codeplex.com/它为我节省了很多时间!

1 个答案:

答案 0 :(得分:2)

因为Button和CustomControl位于Grid的同一行和列中,所以CustomControl可能覆盖了Button。你可能只是看不到它。

如果将CustomControl的背景设置为红色,那么您将看到它所覆盖的区域。

如果希望Button响应鼠标事件,则需要确保CustomControl不会覆盖Button。或者,您可以在CustomControl上将IsHitTestVisible设置为false,或确保它的Background为null。