控制中的单独事件
我想知道是否可以让控件中的单个组件发生事件。例如,我创建了自己的控件,并且使用 VisualStateManager 我能够处理为整个控件触发的多个事件,我希望控件中的切换按钮能够触发鼠标悬停事件。目前,鼠标悬停在控件的任何区域都会触发鼠标悬停,这会破坏我想要获得的彩色动画效果,我希望只有当切换按钮悬停鼠标时才会发生彩色动画,我的控件有一个内容存在,允许其他内容,我不希望那篇文章引发事件。
下面我在 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>
I'm wondering if I can have a individual component in a control have an event. For example, I've created my own control, and with VisualStateManager I'm able to handle several events that fire for the control as a whole, I'd like just my togglebutton in the controlto fire the mouseover event. Currently any area of the control that the mouse is over fires the mouseover which ruins the coloranimation effect i'm trying to get, I want the coloranimation to only happen when the toggle button has a mouse over, my control has a contentpresent allowing for other content, i don't want that piece to fire the event.
Example of what i'm talking about below in generic.xaml file.
<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>
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(2)
鲍勃,您可以像这样从类中访问切换按钮:
ToggleButton myToggleButton = GetTemplateChild("toggleButton") as ToggleButton;
在课堂上创建您想要的活动。您可能需要重写 OnApplyTemplate 方法并在那里创建您的事件,我仍在研究这部分并且尚未完全理解它,您将不得不使用它。我确实覆盖了我的 OnApplyTemplate 并且它对我有用。
另请确保在顶部设置您的模板:
VisualState 可以存在于您设置其他视觉状态的 generic.xaml 文件中,并且不需要位于内部 ToggleButton 中。
Bob, You can access the togglebutton from your class like this:
ToggleButton myToggleButton = GetTemplateChild("toggleButton") as ToggleButton;
Create the events you want in your class. You may need to override the OnApplyTemplate method and create your event there, I'm still researching this part and don't fully understand it yet, you will have to play with it. I did override my OnApplyTemplate and it worked for me.
Also make sure to setup your Template at the top:
The VisualState can exist in the generic.xaml file where you are setting up your other visualstates and does not need to be in the inner ToggleButton.
首先,让我们正确使用术语,您不是在谈论“事件”,而是在谈论“视觉状态”。 “MouseOver”是一种视觉状态。控件中的代码负责决定控件处于哪种视觉状态。
通常,控件中的代码将使用 MouseEnter 和 MouseLeave 事件来设置一个布尔值以指示鼠标位于控件上方,然后调用一些 < code>UpdateStates 方法,开发人员将在其中包含逻辑来确定控件当前应处于哪种视觉状态。
在您的情况下,不要使用控件
MouseEnter
和MouseLeave
事件,而是将这些处理程序附加到您的内部ToggleButton
。First of all lets get our terminology correct, you are not talking about "events" you are talking about "visual states". The "MouseOver" is a visual state. Its the responsibility of code within the control to decide which of the visual states the control is in.
Ordinarily code in the control will use the MouseEnter and MouseLeave events to set a boolean to indicate that the mouse is over the control and then call some
UpdateStates
method in which the developer will include logic to determine which visual states the control ought to be in currently.In your case rather than using the controls
MouseEnter
andMouseLeave
events attach these handlers to your innerToggleButton
instead.