绑定/引用XAML WPF的方法

时间:2014-02-11 17:15:44

标签: c# wpf xaml events binding

我有这个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属性添加到根元素。

3 个答案:

答案 0 :(得分:13)

您可以通过将代码附加到您的ResourceDictionary 来实现。实现这一目标的几个简单步骤是:

  • 假设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");
        }
    }
}
  • 现在,在XAML中设置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?