单独的事件在控制中

本文关键字:控制 事件 单独 | 更新日期: 2023-09-27 18:04:38

我想知道我是否可以在控件中有一个单独的组件有一个事件。例如,我已经创建了自己的控件,并且使用VisualStateManager,我能够处理为整个控件触发的几个事件,我希望控件中的togglebutton触发鼠标悬停事件。目前,鼠标在控件上的任何区域都会触发鼠标在上方,这会破坏我试图获得的颜色动画效果,我希望颜色动画只在切换按钮有鼠标在上方时发生,我的控件有一个允许其他内容的内容呈现,我不希望那块触发事件。

我在下面讨论的泛型的例子。xaml文件。

<Style TargetType="local:MyControl">
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="local:MyControl">
                <Grid>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ViewStates">
                            <VisualState x:Name="Expanded">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="ContentScaleTransform" Storyboard.TargetProperty="ScaleY" To="1" Duration="0"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Collapsed">
                                <Storyboard>
                                    <DoubleAnimation Storyboard.TargetName="ContentScaleTransform" Storyboard.TargetProperty="ScaleY" To="0" Duration="0"/>
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="MouseOver">
                                <Storyboard>
                                    <!-- This fires for any part of the control, is it possible to just create a mouseover for the ToggleButton below? -->
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="{TemplateBinding CornerRadius}" Background="{TemplateBinding Background}">
                        <Grid>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid Margin="3">
                                <Grid.ColumnDefinitions>
                                    <ColumnDefinition Width="*"/>
                                </Grid.ColumnDefinitions>
                                <ToggleButton Grid.Column="0" Content="{TemplateBinding HeaderContent}" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"  RenderTransformOrigin="0.5,0.5" Margin="1" x:Name="ExpandCollapseButton">
                                </ToggleButton>
                            </Grid>
                            <ContentPresenter Grid.Row="1" Margin="5" Content="{TemplateBinding Content}" x:Name="Content">
                                <ContentPresenter.RenderTransform>
                                    <ScaleTransform x:Name="ContentScaleTransform"/>
                                </ContentPresenter.RenderTransform>
                            </ContentPresenter>
                        </Grid>
                    </Border>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

单独的事件在控制中

Bob,你可以像这样从你的类访问togglebutton:

ToggleButton = GetTemplateChild(" ToggleButton ") as ToggleButton;

在类中创建所需的事件。你可能需要重写OnApplyTemplate方法并在那里创建你的事件,我还在研究这部分,还没有完全理解它,你将不得不玩它。我确实覆盖了我的OnApplyTemplate,它为我工作。

ToggleButton myToggleButton;
public override void OnApplyTemplate() {
    base.OnApplyTemplate();
    myToggleButton = GetTemplateChild("toggleButton") as ToggleButton;
    myToggleButton.MouseEnter += new MouseEventHandler(myToggleButton_MouseEnter);
}
void myToggleButton_MouseEnter(object sender, MouseEventArgs e) {
        VisualStateManager.GoToState(this, "MouseEnter", true);
    }

还要确保在顶部设置你的模板:

[TemplateVisualState(Name = "MouseEnter", GroupName = "ViewStates")]

VisualState可以存在于泛型中。设置其他可视状态的xaml文件,不需要在内部ToggleButton中。

<VisualState x:Name="MouseEnter">
    <Storyboard>
        <ColorAnimation Storyboard.TargetName="toggleButton" Storyboard.TargetProperty="(ToggleButton.SomeProperty).(SolidColorBrush.Color)" To="SomeColor"/>
    </Storyboard>
</VisualState>

首先让我们纠正一下术语,你不是在谈论"事件"而是在谈论"视觉状态"。"MouseOver"是一种视觉状态。控件内的代码负责决定控件处于哪种视觉状态。

通常控件中的代码将使用MouseEnter和MouseLeave事件来设置一个布尔值,以指示鼠标在控件上,然后调用一些UpdateStates方法,开发人员将在其中包含逻辑来确定控件当前应该处于哪种视觉状态。

在您的情况下,而不是使用控件MouseEnterMouseLeave事件将这些处理程序附加到您的内部ToggleButton