在ResourceDictionary定义样式后,如何为DataGridRow添加本地EventSetter?
嘿Daniel,这个问题我之前在项目里也踩过坑,给你几个实用的解决方案,挑适合你的场景来用:
方案一:基于已有样式扩展(最推荐,零侵入原有资源)
你不需要替换掉SuperRowStyle,而是在Window的资源里创建一个继承自原有样式的新Style,在这个新样式里补充EventSetter。这样既保留了ResourceDictionary里所有的样式配置,又能添加你需要的事件处理,完全不会覆盖原有样式。
示例代码如下:
<!-- 在Window的Resources节点里定义扩展样式 --> <Window.Resources> <Style x:Key="LocalRowStyle" BasedOn="{StaticResource SuperRowStyle}" TargetType="DataGridRow"> <!-- 在这里添加你需要的EventSetter --> <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick"/> </Style> </Window.Resources> <!-- DataGrid引用这个扩展后的样式 --> <DataGrid RowStyle="{StaticResource LocalRowStyle}" <!-- 其他DataGrid属性 --> />
这个方法的优势是解耦性极强,ResourceDictionary里的样式完全不用改动,只在当前Window里做针对性扩展,非常灵活。
方案二:给ResourceDictionary添加代码隐藏文件
如果你一定要把EventSetter放在ResourceDictionary里统一管理,可以给你的ResourceDictionary文件添加对应的代码隐藏类:
- 右键你的ResourceDictionary文件(比如
DataGridStyles.xaml),新增一个同名的代码文件DataGridStyles.xaml.cs - 在XAML文件的根节点添加
x:Class属性,指向你的代码隐藏类:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" x:Class="YourProjectNamespace.DataGridStyles">
- 在代码隐藏类中编写事件处理方法(注意方法要设为
public或internal):
namespace YourProjectNamespace { public partial class DataGridStyles : ResourceDictionary { public void DataGridRow_MouseDoubleClick(object sender, MouseButtonEventArgs e) { // 这里写你的事件逻辑 } } }
- 最后在ResourceDictionary的
SuperRowStyle里添加EventSetter:
<Style x:Key="SuperRowStyle" TargetType="DataGridRow"> <!-- 你原来的样式配置 --> <EventSetter Event="MouseDoubleClick" Handler="DataGridRow_MouseDoubleClick"/> </Style>
这个方案适合希望所有样式和事件逻辑统一放在ResourceDictionary里的场景,但会让资源文件和代码产生一定耦合。
方案三:用行为实现MVVM友好的事件处理
如果你的项目遵循MVVM模式,不想写代码隐藏的事件处理,可以使用Microsoft.Xaml.Behaviors.Wpf包(原Blend行为库)来实现命令绑定:
- 先通过NuGet安装
Microsoft.Xaml.Behaviors.Wpf包 - 在ResourceDictionary的
SuperRowStyle里添加行为,把事件绑定到ViewModel的命令:
<Style x:Key="SuperRowStyle" TargetType="DataGridRow"> <!-- 你原来的样式配置 --> <Setter Property="behaviors:Interaction.Triggers"> <Setter.Value> <behaviors:EventTrigger EventName="MouseDoubleClick"> <behaviors:InvokeCommandAction Command="{Binding DataContext.RowDoubleClickCommand, RelativeSource={RelativeSource AncestorType=DataGrid}}"/> </behaviors:EventTrigger> </Setter.Value> </Setter> </Style>
这样就能把事件逻辑完全放到ViewModel中,符合MVVM的设计原则,而且不需要任何代码隐藏。
内容的提问来源于stack exchange,提问作者Daniel
相关产品推荐
相关产品推荐

