控制中的独立事件

时间:2011-08-03 20:00:40

标签: c# silverlight mouseover visualstatemanager

我想知道我是否可以在控件中有一个单独的组件有一个事件。例如,我已经创建了自己的控件,并且使用VisualStateManager我能够处理几个为控件整体触发的事件,我只想在控件中触发togglebutton来触发mouseover事件。目前鼠标所控制的任何区域都会触发鼠标悬停,这会破坏我想要获得的coloranimation效果,我希望只有当切换按钮鼠标悬停时才会发生coloranimation,我的控件有一个内容存在允许其他内容,我不希望那件作品发生。

我在generic.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>

2 个答案:

答案 0 :(得分:2)

Bob,您可以像这样访问您班级的togglebutton:

ToggleButton myToggleButton = GetTemplateChild(“toggleButton”)为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可以存在于generic.xaml文件中,您可以在其中设置其他视觉状态,而不需要位于内部ToggleButton中。

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

答案 1 :(得分:1)

首先让我们的术语正确,你不是在谈论你所谈论的“视觉状态”的“事件”。 “MouseOver”是一种视觉状态。控制中的代码负责决定控件所处的视觉状态。

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

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