我有这个xaml
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:l="clr-namespace:My.Windows"
>
<ObjectDataProvider x:Key="TitledWindow_Test" MethodName="Test" ObjectInstance={x:Type l:TitledWindow}">
<ControlTemplate x:Key="TitledWindowControlTemplateKey" x:Name="PART_ControlTemplate" TargetType="{x:Type l:TitledWindow}"
<Rectangle>
<Rectangle.Style>
<EventSetter Event="Mouse.MouseEnter" Handler="{StaticResource TitledWindow_Test}">
</Rectangle.Style>
</Rectangle>
</ControlTemplate>
</ResourceDictionary>
我的c#代码:
namespace My.Windows
{
public partial class TitledWindow : Window
{
public void Test()
{
MessageBox.Show("Test");
}
}
}
问题是我收到以下错误:
错误1
'ResourceDictionary'根元素需要x:Class属性来支持事件
XAML文件中的处理程序。删除MouseEnter事件的事件处理程序,
或者将x:Class属性添加到根元素。
答案 0 :(得分:13)
您可以通过将代码附加到您的ResourceDictionary 来实现。实现这一目标的几个简单步骤是:
CustomResources.xaml
。在名称为CustomResources.xaml.cs
的ResourceDictionary之外的同一目录中添加另一个文件。创建继承自ResourceDictionary的partial class CustomResources
。为MouseEnter声明你的处理程序,后面的代码就准备好了。
using System;
using System.Windows;
namespace WpfApplication1
{
public partial class CustomResources : ResourceDictionary
{
public void MouseEnter(object sender, EventArgs e)
{
MessageBox.Show("Test");
}
}
}
x:Class
属性并将处理程序设置为MouseEnter
。XAML:
<ResourceDictionary
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
x:Class="WpfApplication1.CustomResources"
xmlns:local="clr-namespace:WpfApplication1">
<ControlTemplate x:Key="TitledWindowControlTemplateKey"
x:Name="PART_ControlTemplate"
TargetType="{x:Type local:TitleWindow}">
<Rectangle>
<Rectangle.Style>
<Style TargetType="Rectangle">
<EventSetter Event="Mouse.MouseEnter" Handler="MouseEnter"/>
</Style>
</Rectangle.Style>
</Rectangle>
</ControlTemplate>
</ResourceDictionary>
答案 1 :(得分:1)
问题在于Template
需要知道它应用的内容是否有MouseEnter
。不幸的是,即使将x:Type
应用于模板,xaml编译器还没有足够的功能继续下去。
我之前已经做了类似的事情,让ResourceDictionary
认识到我正在模仿的孔隙,看起来我用一种风格来绕过它。 http://winchrome.codeplex.com/SourceControl/latest#WinChrome/UI/VS2012ResourceDictionary.xaml中的完整代码。
<ResourceDictionary ... >
<Style x:Key="CloseButtonStyle" TargetType="{x:Type Button}" >
...
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type Button}">
<Border x:Name="bd" ....>
....
</Border>
<ControlTemplate.Triggers>
<Trigger Property="IsMouseOver" Value="True" SourceName="bd">
<Setter Property="Background" TargetName="bd" Value="{DynamicResource {x:Static SystemColors.ControlLightLightBrushKey}}"/>
...
</Trigger>
<Trigger Property="IsPressed" Value="True">
<Setter Property="Background" TargetName="bd">
...
</Setter>
</Trigger>
</ControlTemplate.Triggers>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
但是,您希望然后通过objectDataPresenter
将处理程序绑定到{StaticResource ...}
上的方法,我不确定您是否可以。相反,您可能最好使用普通绑定DataContext
绑定到{Binding Path=...}
,我认为您仍然可以通过DataContext
提供{StaticResource.. }
。
答案 2 :(得分:1)
您需要添加x:class属性并指定资源的位置以及事件处理程序的位置。 有关此示例,请参阅Is it possible to set code behind a resource dictionary in WPF for event handling?。