XAML WPF 的绑定/引用方法

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/21708553/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me): StackOverFlow

提示:将鼠标放在中文语句上可以显示对应的英文。显示中英文
时间:2020-09-13 10:48:02  来源:igfitidea点击:

Binding/Referencing Method to XAML WPF

c#wpfxamleventsbinding

提问by jovanMeshkov

I have this xaml

我有这个 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>

And my c# code:

还有我的 C# 代码:

namespace My.Windows
{
    public partial class TitledWindow : Window
    {
        public void Test()
        {
            MessageBox.Show("Test");
        }
    }
}

The problem is that i get the following error:

问题是我收到以下错误:

Error 1
'ResourceDictionary' root element requires a x:Class attribute to support event handlers in the XAML file. Either remove the event handler for the MouseEnter event, or add a x:Class attribute to the root element.

错误 1
'ResourceDictionary' 根元素需要 ax:Class 属性来支持 XAML 文件中的事件处理程序。删除 MouseEnter 事件的事件处理程序,或将 ax:Class 属性添加到根元素。

回答by Rohit Vats

Well you can do that by attaching code behind to your ResourceDictionary. Few simple steps to achieve that are:

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

  • Say ResourceDictionary file name is CustomResources.xaml. Add another file in same directory besides your ResourceDictionary with name CustomResources.xaml.cs. Create partial class CustomResourcesinheriting from ResourceDictionary.
  • 说 ResourceDictionary 文件名是CustomResources.xaml. 除了名称为 ResourceDictionary 之外,在同一目录中添加另一个文件CustomResources.xaml.cs。创建partial class CustomResources继承自 ResourceDictionary。

Declare your handler for MouseEnter and code behind is ready.

为 MouseEnter 声明您的处理程序,并且后面的代码已准备就绪。

using System;
using System.Windows;
namespace WpfApplication1
{
    public partial class CustomResources : ResourceDictionary
    {
        public void MouseEnter(object sender, EventArgs e)
        {
            MessageBox.Show("Test");
        }
    }
}
  • Now, in XAML set x:Classattribute and set handler to MouseEnter.
  • 现在,在 XAML 中设置x:Class属性并将处理程序设置为MouseEnter.

XAML :

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>

回答by AlSki

The problem is that the Templateneeds to know if what it is being applied to has a MouseEnter. Unfortunately even by applying your x:Typeto the template, the xaml compiler doesn't have enough to go on.

问题是Template需要知道它所应用的内容是否具有MouseEnter. 不幸的是,即使将您的应用程序应用于x:Type模板,xaml 编译器也没有足够的能力继续下去。

I have done something similar before in getting the ResourceDictionaryto recognise the porepoties of what I'm templating to and it looks like I used a style to get around it. Full code in http://winchrome.codeplex.com/SourceControl/latest#WinChrome/UI/VS2012ResourceDictionary.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>

However you want to then bind your handler to a method on your objectDataPresentervia a {StaticResource ...}which I'm not sure that you can. Instead you might be better to instead bind onto the DataContextusing a normal binding {Binding Path=...}, I think you might still be able to provide the DataContextvia the {StaticResource.. }.

但是,您想将您的处理程序绑定到您的objectDataPresentervia a上的方法{StaticResource ...},我不确定您是否可以。相反,您最好DataContext使用普通绑定绑定到{Binding Path=...},我认为您仍然可以DataContext通过{StaticResource.. }.

回答by Brinky

You need to add the x:class attribute and specify where the resource is, and where the event handler would be located. See Is it possible to set code behind a resource dictionary in WPF for event handling?for an example of this.

您需要添加 x:class 属性并指定资源的位置以及事件处理程序的位置。请参阅是否可以在 WPF 中的资源字典后面设置代码以进行事件处理?举个例子。