ResourceDictionary WPF 风格的交互触发器

编程入门 行业动态 更新时间:2024-10-27 08:27:59
本文介绍了ResourceDictionary WPF 风格的交互触发器的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧! 问题描述

我有一个 ComboBox,我需要在我的应用程序的几个地方使用它,所以我在 ResourceDictionary 中设置了该 ComboBox 的大部分属性code> 并将其用作我需要的样式.

I have a ComboBox which I need to use in several places in my application, so I set most of the properties of that ComboBox in ResourceDictionary and use that as a Style where ever I need it.

ComboBox 的样式是:

<Style TargetType="{x:Type ComboBox}" x:Key="ComboBoxBranch"> <Setter Property="ItemsSource" Value="{Binding Branches}"></Setter> <Setter Property="DisplayMemberPath" Value="BranchName"></Setter> <Setter Property="SelectedItem" Value="{Binding SelectedBranch}"></Setter> </Style>

我在我的 XAML 中像这样使用它:

and I am using it like this in my XAML:

<ComboBox Style="{StaticResource ComboBoxBranch}"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding SelectCustomerCommand}" CommandParameter="{Binding SelectedBranch}" ></i:InvokeCommandAction> </i:EventTrigger> </i:Interaction.Triggers> </ComboBox>

我想将交互触发代码也移动到ResourceDictionary,所以我不需要在我所有的xaml 中编写它.有没有可能?

I want to move the interaction trigger code as well to ResourceDictionary, so I don't need to write it in all my xamls. Is it possible somehow?

推荐答案

据我所知,Interaction.Triggers 不能分别应用于 Style 和 ResourceDictionary.但是您可以这样做,将 ComboBox 确定为具有 x:Shared="False" 的资源,并为 ContentControl 引用它,如下所示:

As far as I know, Interaction.Triggers can not be applied in Style, respectively and in a ResourceDictionary. But you can do so, to determine the ComboBox as a resource with x:Shared="False" and reference it for ContentControl like this:

<Window.Resources> <ComboBox x:Key="MyComboBox" x:Shared="False" ItemsSource="{Binding Branches}" DisplayMemberPath="BranchName" SelectedItem="{Binding SelectedBranch}"> <i:Interaction.Triggers> <i:EventTrigger EventName="SelectionChanged"> <i:InvokeCommandAction Command="{Binding SelectCustomerCommand}" /> </i:EventTrigger> </i:Interaction.Triggers> </ComboBox> </Window.Resources> <Grid> <ContentControl Name="MyComboBox1" Width="100" Height="30" HorizontalAlignment="Left" Content="{StaticResource MyComboBox}" /> <ContentControl Name="MyComboBox2" Width="100" Height="30" HorizontalAlignment="Right" Content="{StaticResource MyComboBox}" /> </Grid>

当 x:Shared="True" 默认情况下,一种样式对所有人都是通用的 - 在这种情况下,系统会对重复的 Content 发誓.当 x:Shared="False" when 为每个元素创建样式时,只要它请求它.引用自 MSDN:

When x:Shared="True" by default then one Style is common to all - in this case, the system swears on the duplicate Content. When x:Shared="False" when is created Style for each element whenever it its request. Quote from MSDN:

当设置为 false 时,修改 WPF 资源检索行为,以便对属性资源的请求为每个请求创建一个 新实例,而不是为所有请求共享相同的实例请求.

When set to false, modifies WPF resource-retrieval behavior so that requests for the attributed resource create a new instance for each request instead of sharing the same instance for all requests.

有关更多信息,请参阅:

For more information, please see:

MSDN:x:共享属性

替代解决方案

这里, Mr.Vspivak 发布了一个解决方案,可以让你轻松设置Interaction.Triggers in Style.

示例:

MainWindow.xaml

<Window x:Class="StylesInteractivity.MainWindow" xmlns="schemas.microsoft/winfx/2006/xaml/presentation" xmlns:x="schemas.microsoft/winfx/2006/xaml" xmlns:ie="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" xmlns:Core="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" xmlns:int="clr-namespace:System.Windows.Interactivity" xmlns:si="clr-namespace:StylesInteractivity" Title="MainWindow" Height="350" Width="525"> <Window.Resources> <si:ViewModel x:Key="Model" /> </Window.Resources> <Grid> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition /> </Grid.ColumnDefinitions> <TextBlock Grid.Column="1" x:Name="_tblock" Text="Default" HorizontalAlignment="Center" VerticalAlignment="Center" FontSize="24" FontWeight="Bold" /> <ListBox ItemsSource="{Binding Source={StaticResource Model}, Path=DataSource}" Grid.Column="0" HorizontalAlignment="Center" VerticalAlignment="Center"> <ListBox.ItemContainerStyle> <Style TargetType="ListBoxItem"> <Setter Property="FontSize" Value="24"/> <Setter Property="FontWeight" Value="Bold"/> <Setter Property="int:InteractivityItems.Template"> <Setter.Value> <int:InteractivityTemplate> <int:InteractivityItems> <int:InteractivityItems.Behaviors> <int:FlipOnHover /> </int:InteractivityItems.Behaviors> <int:InteractivityItems.Triggers> <ie:EventTrigger EventName="MouseMove"> <Core:ChangePropertyAction PropertyName="Text" TargetObject="{Binding ElementName=_tblock}" Value="{Binding}" /> </ie:EventTrigger> </int:InteractivityItems.Triggers> </int:InteractivityItems> </int:InteractivityTemplate> </Setter.Value> </Setter> </Style> </ListBox.ItemContainerStyle> </ListBox> </Grid> </Window>

InteractivityHelper.cs

/// <summary> /// <see cref="FrameworkTemplate"/> for InteractivityElements instance /// <remarks>Subclassed for forward compatibility, perhaps one day <see cref="FrameworkTemplate"/> </remarks> /// <remarks>will not be partially internal</remarks> /// </summary> public class InteractivityTemplate : DataTemplate { } /// <summary> /// Holder for interactivity entries /// </summary> public class InteractivityItems : FrameworkElement { private List<Behavior> _behaviors; private List<TriggerBase> _triggers; /// <summary> /// Storage for triggers /// </summary> public List<TriggerBase> Triggers { get { if (_triggers == null) _triggers = new List<TriggerBase>(); return _triggers; } } /// <summary> /// Storage for Behaviors /// </summary> public List<Behavior> Behaviors { get { if (_behaviors == null) _behaviors = new List<Behavior>(); return _behaviors; } } #region Template attached property public static InteractivityTemplate GetTemplate(DependencyObject obj) { return (InteractivityTemplate)obj.GetValue(TemplateProperty); } public static void SetTemplate(DependencyObject obj, InteractivityTemplate value) { obj.SetValue(TemplateProperty, value); } public static readonly DependencyProperty TemplateProperty = DependencyProperty.RegisterAttached("Template", typeof(InteractivityTemplate), typeof(InteractivityItems), new PropertyMetadata(default(InteractivityTemplate), OnTemplateChanged)); private static void OnTemplateChanged( DependencyObject d, DependencyPropertyChangedEventArgs e) { InteractivityTemplate dt = (InteractivityTemplate)e.NewValue; #if(!SILVERLIGHT) dt.Seal(); #endif InteractivityItems ih = (InteractivityItems)dt.LoadContent(); BehaviorCollection bc = Interaction.GetBehaviors(d); TriggerCollection tc = Interaction.GetTriggers(d); foreach (Behavior behavior in ih.Behaviors) bc.Add(behavior); foreach (TriggerBase trigger in ih.Triggers) tc.Add(trigger); } #endregion }

FlipOnHover.cs

public class FlipOnHover : Behavior<FrameworkElement> { protected override void OnAttached() { AssociatedObject.MouseEnter += AssociatedObject_MouseEnter; AssociatedObject.MouseLeave += AssociatedObject_MouseLeave; Transform t = AssociatedObject.RenderTransform; AssociatedObject.RenderTransform = new TransformGroup(); ((TransformGroup)AssociatedObject.RenderTransform).Children.Add(t); ((TransformGroup)AssociatedObject.RenderTransform).Children.Add(new ScaleTransform()); base.OnAttached(); } void AssociatedObject_MouseLeave(object sender, System.Windows.Input.MouseEventArgs e) { ((ScaleTransform)((TransformGroup)AssociatedObject.RenderTransform).Children[1]).ScaleY = 1; } void AssociatedObject_MouseEnter(object sender, System.Windows.Input.MouseEventArgs e) { ((ScaleTransform)((TransformGroup)AssociatedObject.RenderTransform).Children[1]).CenterX = AssociatedObject.ActualWidth / 2; ((ScaleTransform)((TransformGroup)AssociatedObject.RenderTransform).Children[1]).CenterY = AssociatedObject.ActualHeight / 2; ((ScaleTransform)((TransformGroup)AssociatedObject.RenderTransform).Children[1]).ScaleY=-1; } protected override void OnDetaching() { base.OnDetaching(); AssociatedObject.MouseEnter -= AssociatedObject_MouseEnter; AssociatedObject.MouseLeave -= AssociatedObject_MouseLeave; } }

ViewModel.cs

public class ViewModel { private ObservableCollection<String> _dataSource = new ObservableCollection<string>(); public ViewModel() { _dataSource.Add("Cat"); _dataSource.Add("Dog"); _dataSource.Add("Mouse"); _dataSource.Add("Owl"); _dataSource.Add("Rabbit"); } public IEnumerable<string> DataSource { get { return _dataSource; } } }

有关更多信息,请参阅此链接:

For more info, see this link:

使用交互WPF/Silverlight 样式中的行为和操作

更多推荐

ResourceDictionary WPF 风格的交互触发器

本文发布于:2023-11-06 04:49:35,感谢您对本站的认可!
本文链接:https://www.elefans.com/category/jswz/34/1562751.html
版权声明:本站内容均来自互联网,仅供演示用,请勿用于商业和其他非法用途。如果侵犯了您的权益请与我们联系,我们将在24小时内删除。
本文标签:触发器   风格   ResourceDictionary   WPF

发布评论

评论列表 (有 0 条评论)
草根站长

>www.elefans.com

编程频道|电子爱好者 - 技术资讯及电子产品介绍!