一、样式触发器
样式触发器可以在指定的控件属性满足某种条件后进行一些样式的变换,当触发条件不满足时恢复原样。
样式触发器的简单使用
<Window.Resources> <Style x:Key="checkBoxStyle" TargetType="CheckBox"> <Style.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <CheckBox Content="Schuyler" Style="{StaticResource checkBoxStyle}"/> </Grid>
样式触发器的优先级
使用时需要注意,如果使用内联样式直接在控件属性中进行设置,由于内联样式的优先级最高,所以触发器不会有效果。
因此触发器设置的样式,如果在触发前需要进行设置,可以配合Setter
进行设置。
<Window.Resources> <Style x:Key="checkBoxStyle" TargetType="CheckBox"> <Setter Property="Foreground" Value="Green"/> <Style.Triggers> <Trigger Property="IsChecked" Value="True"> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <CheckBox Content="Schuyler" Style="{StaticResource checkBoxStyle}"/> </Grid>
使用触发器的时候会发现有些样式是无法展示效果的(例如Button控件的Background属性),这是因为WPF的控件模板对其控件进行了设置,
而模板中设置的属性、触发器优先级别高于外界的触发器,因此外界触发器不会触发(或者说触发了但是被覆盖了?)。
控件状态作为触发条件
触发器将控件的样式作为触发条件外,还可以将控件的状态(例如鼠标的悬浮、按压等)作为触发条件。
由于后面定义的触发器会将前面的触发器效果覆盖,因此在使用时要注意触发器的位置。
<Window.Resources> <Style x:Key="buttonStyle" TargetType="Button"> <Style.Triggers> <Trigger Property="IsMouseOver" Value="true"> <Setter Property="Foreground" Value="Blue"/> </Trigger> <!--这里注意按压触发器放在悬浮触发器之后,否则会被悬浮触发器覆盖,导致无法展示效果--> <Trigger Property="IsPressed" Value="True"> <Setter Property="Foreground" Value="Red"/> </Trigger> </Style.Triggers> </Style> </Window.Resources> <Grid> <Button Content="Schuyler" Height="100" Width="100" Style="{StaticResource buttonStyle}"/> </Grid>
多条件样式触发器
多条件触发器是指只有当指定的多个属性满足条件时,才会触发。
<Window.Resources> <Style x:Key="buttonStyle" TargetType="Button"> <Style.Triggers> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="Width" Value="100"/> <Condition Property="IsPressed" Value="True"/> </MultiTrigger.Conditions> <MultiTrigger.Setters> <Setter Property="Foreground" Value="Red"/> </MultiTrigger.Setters> </MultiTrigger> </Style.Triggers> </Style> </Window.Resources>
<Grid>
<Button Content="Schuyler" Height="100" Width="100" Style="{StaticResource buttonStyle}"/>
</Grid>
二、DataTrigger
当触发条件不是元素的属性,而是指定的某个绑定数据的时,可以使用DataTrigger
触发器。
<Style x:Key="UserNameTextBoxStyle" TargetType="TextBox"> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TextBox}"> ...... <ControlTemplate.Triggers> ...... <DataTrigger Binding="{Binding Path=Text, RelativeSource={RelativeSource Mode=Self}}" Value=""> <Setter Property="Visibility" Value="Visible" TargetName="markText"/> </DataTrigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style>
DataTrigger上除了进行简单的控件属性设置外,还可以使用DataTrigger.EnterActions与DataTrigger.ExitActions
,定义在触发器条件满足时执行的动作和触发器条件不再满足时执行的行为(动作的集合),这里的动作是指任何派生自TriggerAction类的对象,
常用BeginStoryboard、StopStoryboard等动画操作动作。详细案例可以参考动画章节中的动画操作内容。
三、事件触发器
事件触发器EventTrigger可以在指定控件的指定路由事件发生时触发,通常会通过<BeginStoryboard>、<StopStoryboard>、<PauseStoryboard>、<ResumeStoryboard>等进行一些动画操作。
EventTrigger可以放置在<Window.Triggers>元素中,与<Window.Resources>元素保持同级,此时需要设置SourceName和Storyboard.TargetName属性,用来指定使用此事件触发器的控件名称,设置后作用域内对应的控件会自动绑定该事件触发器。
<Window.Triggers> <EventTrigger RoutedEvent="Button.Click" SourceName="btn"> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:1" To="300" Storyboard.TargetName="btn" Storyboard.TargetProperty="Width"/> </Storyboard> </BeginStoryboard> <!--<StopStoryboard></StopStoryboard> <PauseStoryboard></PauseStoryboard> <ResumeStoryboard></ResumeStoryboard>--> </EventTrigger> </Window.Triggers>
EventTrigger
还可以放置在<Style.Triggers>
元素中,此时不能设置SourceName
和Storyboard.TargetName
属性,
事件触发器跟随样式,哪个控件采用该样式,哪个控件就绑定了这个事件触发器。
<Window.Resources> <Style x:Key="buttonStyle" TargetType="Button"> <Style.Triggers> <EventTrigger RoutedEvent="Click"> <BeginStoryboard> <Storyboard> <DoubleAnimation Duration="0:0:1" To="300" Storyboard.TargetProperty="Width"/> </Storyboard> </BeginStoryboard> <!--<StopStoryboard></StopStoryboard> <PauseStoryboard></PauseStoryboard> <ResumeStoryboard></ResumeStoryboard>--> </EventTrigger> </Style.Triggers> </Style> </Window.Resources>
除了Window
、Style
外,EventTrigger
还可以设置在任何其他控件的Triggers
属性下
- 注意,事件触发器与样式、数据触发器所不同的一个特点是,对于控件的内联触发器设置,仅能设置
EventTrigger
。
<Button> <Button.Triggers> <EventTrigger RoutedEvent="MouseDown"> ...... </EventTrigger> </Button.Triggers> </Button>
RoutedEvent属性的有效值 在使用事件触发器的时候,由于RoutedEvent属性在赋值时是没有提示信息的,因此会产生一个疑问,有效值是什么?要去哪里找?这里提供两种方法,
一种是直接去官网找一下公布的路由事件,另外一种就是通过静态方法EventManager.GetRoutedEvents()可以获得内置的所有` 类型。 有效值列表
[0]: {FrameworkElement.RequestBringIntoView} [1]: {FrameworkElement.SizeChanged} [2]: {FrameworkElement.Loaded} [3]: {FrameworkElement.Unloaded} [4]: {ToolTipService.ToolTipOpening} [5]: {ToolTipService.ToolTipClosing} [6]: {ContextMenuService.ContextMenuOpening} [7]: {ContextMenuService.ContextMenuClosing} [8]: {Mouse.PreviewMouseDown} [9]: {Mouse.MouseDown} [10]: {Mouse.PreviewMouseUp} [11]: {Mouse.MouseUp} [12]: {UIElement.PreviewMouseLeftButtonDown} [13]: {UIElement.MouseLeftButtonDown} [14]: {UIElement.PreviewMouseLeftButtonUp} [15]: {UIElement.MouseLeftButtonUp} [16]: {UIElement.PreviewMouseRightButtonDown} [17]: {UIElement.MouseRightButtonDown} [18]: {UIElement.PreviewMouseRightButtonUp} [19]: {UIElement.MouseRightButtonUp} [20]: {Mouse.PreviewMouseMove} [21]: {Mouse.MouseMove} [22]: {Mouse.PreviewMouseWheel} [23]: {Mouse.MouseWheel} [24]: {Mouse.MouseEnter} [25]: {Mouse.MouseLeave} [26]: {Mouse.GotMouseCapture} [27]: {Mouse.LostMouseCapture} [28]: {Mouse.QueryCursor} [29]: {Stylus.PreviewStylusDown} [30]: {Stylus.StylusDown} [31]: {Stylus.PreviewStylusUp} [32]: {Stylus.StylusUp} [33]: {Stylus.PreviewStylusMove} [34]: {Stylus.StylusMove} [35]: {Stylus.PreviewStylusInAirMove} [36]: {Stylus.StylusInAirMove} [37]: {Stylus.StylusEnter} [38]: {Stylus.StylusLeave} [39]: {Stylus.PreviewStylusInRange} [40]: {Stylus.StylusInRange} [41]: {Stylus.PreviewStylusOutOfRange} [42]: {Stylus.StylusOutOfRange} [43]: {Stylus.PreviewStylusSystemGesture} [44]: {Stylus.StylusSystemGesture} [45]: {Stylus.GotStylusCapture} [46]: {Stylus.LostStylusCapture} [47]: {Stylus.StylusButtonDown} [48]: {Stylus.StylusButtonUp} [49]: {Stylus.PreviewStylusButtonDown} [50]: {Stylus.PreviewStylusButtonUp} [51]: {Keyboard.PreviewKeyDown} [52]: {Keyboard.KeyDown} [53]: {Keyboard.PreviewKeyUp} [54]: {Keyboard.KeyUp} [55]: {Keyboard.PreviewGotKeyboardFocus} [56]: {Keyboard.GotKeyboardFocus} [57]: {Keyboard.PreviewLostKeyboardFocus} [58]: {Keyboard.LostKeyboardFocus} [59]: {TextCompositionManager.PreviewTextInput} [60]: {TextCompositionManager.TextInput} [61]: {DragDrop.PreviewQueryContinueDrag} [62]: {DragDrop.QueryContinueDrag} [63]: {DragDrop.PreviewGiveFeedback} [64]: {DragDrop.GiveFeedback} [65]: {DragDrop.PreviewDragEnter} [66]: {DragDrop.DragEnter} [67]: {DragDrop.PreviewDragOver} [68]: {DragDrop.DragOver} [69]: {DragDrop.PreviewDragLeave} [70]: {DragDrop.DragLeave} [71]: {DragDrop.PreviewDrop} [72]: {DragDrop.Drop} [73]: {Touch.PreviewTouchDown} [74]: {Touch.TouchDown} [75]: {Touch.PreviewTouchMove} [76]: {Touch.TouchMove} [77]: {Touch.PreviewTouchUp} [78]: {Touch.TouchUp} [79]: {Touch.GotTouchCapture} [80]: {Touch.LostTouchCapture} [81]: {Touch.TouchEnter} [82]: {Touch.TouchLeave} [83]: {FocusManager.GotFocus} [84]: {FocusManager.LostFocus} [85]: {ManipulationDevice.ManipulationStarting} [86]: {ManipulationDevice.ManipulationStarted} [87]: {ManipulationDevice.ManipulationDelta} [88]: {ManipulationDevice.ManipulationInertiaStarting} [89]: {ManipulationDevice.ManipulationBoundaryFeedback} [90]: {ManipulationDevice.ManipulationCompleted} [91]: {Control.PreviewMouseDoubleClick} [92]: {Control.MouseDoubleClick} [93]: {ScrollViewer.ScrollChanged} [94]: {ScrollBar.Scroll} [95]: {Thumb.DragStarted} [96]: {Thumb.DragDelta} [97]: {Thumb.DragCompleted} [98]: {RangeBase.ValueChanged} [99]: {TextBoxBase.TextChanged}
静态方法查看 var routEvents = EventManager.GetRoutedEvents(); foreach(var routEvent in routEvents) { var name = routEvent.Name; }
来源:https://blog.csdn.net/jjailsa/article/details/135337152
标签:控件,触发器,Stylus,DragDrop,Touch,WPF,Mouse From: https://www.cnblogs.com/ywtssydm/p/18362791