ResourceDictionary中的交互触发器WPF

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

我有一个 ComboBox ,我需要在我的应用程序中的几个地方使用,所以我设置 ComboBox 在 ResourceDictionary ,并将其用作我需要它的样式。

ComboBox 是:

< Style TargetType ={x:Type ComboBox}x:Key =ComboBoxBranch> < Setter Property =ItemsSourceValue ={Binding Branches}>< / Setter> < Setter Property =DisplayMemberPathValue =BranchName>< / Setter> < Setter Property =SelectedItemValue ={Binding SelectedBranch}>< / Setter> < / Style>

我在我的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 ,所以我不需要写在所有的xamls。可能以某种方式?

解决方案

据我所知, Interaction.Triggers 不能分别应用在Style中和ResourceDictionary中。但是你可以这样做,确定 ComboBox 作为一个资源与 x:Shared =False ContentControl 如下:

< Window.Resources> < ComboBox x:Key =MyComboBoxx: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 Horizo​​ntalAlignment =Left Content ={StaticResource MyComboBox} /> < ContentControl Name =MyComboBox2 Width =100 Height =30 Horizo​​ntalAlignment =Right Content = {StaticResource MyComboBox}/> < / Grid>

当 x:Shared =True默认情况下,一个样式是所有的共同 - 在这种情况下,系统发出重复的内容。当 x:Shared =False时创建每个元素的Style,当它请求时。引自 MSDN :

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

有关详情,请参阅:

MSDN:x:共享属性

编辑:替代解决方案

Here,Mr.Vspivak发布了一个解决方案,允许您轻松地在样式中设置 Interaction.Triggers 。

示例:

MainWindow.xaml p>

< 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 =MainWindowHeight =350Width =525> < Window.Resources> < si:ViewModel x:Key =Model/> < /Window.Resources> < grid> < Grid.ColumnDefinitions> < ColumnDefinition /> < ColumnDefinition /> < /Grid.ColumnDefinitions> < TextBlock Grid.Column =1x:Name =_ tblock Text =Default Horizo​​ntalAlignment =Center VerticalAlignment = Center FontSize =24 FontWeight =Bold/> < ListBox ItemsSource ={Binding Source = {StaticResource Model},Path = DataSource} Grid.Column =0 Horizo​​ntalAlignment =Center VerticalAlignment =Center> < ListBox.ItemContainerStyle> < Style TargetType =ListBoxItem> < Setter Property =FontSizeValue =24/> < Setter Property =FontWeightValue =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/>对于InteractivityElements实例 ///< remarks>子类为向前兼容性,也许有一天< see cref =FrameworkTemplate/> < / remarks> ///< remarks>不会部分内部< / remarks> ///< / summary> public class InteractivityTemplate:DataTemplate { } ///< summary> ///用于交互项的持有者 ///< / summary> public class InteractivityItems:FrameworkElement { private List< Behavior> _行为; private List< TriggerBase> _triggers; ///< summary> ///触发器的存储 ///< / summary> public List< TriggerBase>触发器 { get { if(_triggers == null) _triggers = new List< TriggerBase>(); return _triggers; } } ///< summary> ///行为存储 ///< / summary> public List< Behavior>行为 { get { if(_behaviors == null) _behaviors = new List< Behavior>(); return _behaviors; } } #region模板附加属性 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(ih.Behaviors中的行为行为) bc.Add(behavior); foreach(ih.Triggers中的TriggerBase触发器) tc.Add(trigger); } #endregion }

code> 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)。儿童[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; } } }

有关详细信息, p>

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

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.

Style for the ComboBox is:

<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>

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>

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?

解决方案

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>

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:

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:Shared Attribute

Edit: alternative solution

Here, Mr.Vspivak published a solution that allows you easily set the Interaction.Triggers in Style.

Example:

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:

Using Interactivity Behaviors and Actions in WPF/Silverlight Styles

更多推荐

ResourceDictionary中的交互触发器WPF

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

发布评论

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

>www.elefans.com

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