是否可以在 WPF 中的资源字典后面设置代码以进行事件处理?

声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow 原文地址: http://stackoverflow.com/questions/92100/
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-08 19:37:39  来源:igfitidea点击:

Is it possible to set code behind a resource dictionary in WPF for event handling?

wpf

提问by Crippeoblade

Is it possible to set code behind a resource dictionary in WPF. For example in a usercontrol for a button you declare it in XAML. The event handling code for the button click is done in the code file behind the control. If I was to create a data template with a button how can I write the event handler code for it's button click within the resource dictionary.

是否可以在 WPF 中的资源字典后面设置代码。例如,在按钮的用户控件中,您可以在 XAML 中声明它。按钮单击的事件处理代码在控件后面的代码文件中完成。如果我要创建一个带有按钮的数据模板,我如何为资源字典中的按钮单击编写事件处理程序代码。

回答by ageektrapped

I think what you're asking is you want a code-behind file for a ResourceDictionary. You can totally do this! In fact, you do it the same way as for a Window:

我认为您要问的是您想要一个 ResourceDictionary 的代码隐藏文件。你完全可以做到这一点!实际上,您的操作方式与 Window 相同:

Say you have a ResourceDictionary called MyResourceDictionary. In your MyResourceDictionary.xaml file, put the x:Class attribute in the root element, like so:

假设您有一个名为 MyResourceDictionary 的 ResourceDictionary。在 MyResourceDictionary.xaml 文件中,将 x:Class 属性放在根元素中,如下所示:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
                    x:Class="MyCompany.MyProject.MyResourceDictionary"
                    x:ClassModifier="public">

Then, create a code behind file called MyResourceDictionary.xaml.cs with the following declaration:

然后,使用以下声明创建一个名为 MyResourceDictionary.xaml.cs 的代码隐藏文件:

namespace MyCompany.MyProject
{
    partial class MyResourceDictionary : ResourceDictionary
    { 
       public MyResourceDictionary()
       {
          InitializeComponent();
       }     
       ... // event handlers ahead..
    }
}

And you're done. You can put whatever you wish in the code behind: methods, properties and event handlers.

你已经完成了。您可以在后面的代码中放置任何您想要的内容:方法、属性和事件处理程序。

== Update for Windows 10 apps ==

== Windows 10 应用程序更新 ==

And just in case you are playing with UWPthere is one more thing to be aware of:

以防万一您正在使用UWP,还有一件事需要注意:

<Application x:Class="SampleProject.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:rd="using:MyCompany.MyProject">
<!-- no need in x:ClassModifier="public" in the header above -->

    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>

                <!-- This will NOT work -->
                <!-- <ResourceDictionary Source="/MyResourceDictionary.xaml" />-->

                <!-- Create instance of your custom dictionary instead of the above source reference -->
                <rd:MyResourceDictionary />

            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>

</Application>

回答by Phobis

I disagree with "ageektrapped"... using the method of a partial class is not a good practice. What would be the purpose of separating the Dictionary from the page then?

我不同意“ageektrapped”……使用部分类的方法不是一个好习惯。那么将字典与页面分开的目的是什么?

From a code-behind, you can access a x:Name element by using:

从代码隐藏中,您可以使用以下方法访问 ax:Name 元素:

Button myButton = this.GetTemplateChild("ButtonName") as Button;
if(myButton != null){
   ...
}

You can do thisin the OnApplyTemplate method if you want to hookup to controls when your custom control loads. OnApplyTemplate needs to be overridden to do this. This is a common practice and allows your style to stay disconnected from the control. (The style should not depend on the control, but the control should depend on having a style).

如果您想在自定义控件加载时连接到控件,则可以在 OnApplyTemplate 方法中执行操作。OnApplyTemplate 需要被覆盖才能做到这一点。这是一种常见做法,可让您的风格与控件保持脱节。(样式不应该依赖于控件,但控件应该依赖于具有样式)。

回答by Pete Maher

Gishu - whilst this might seem to be a "generally not to be encouraged practice" Here is one reason you might want to do it:

Gishu - 虽然这似乎是一种“通常不鼓励的做法”,但您可能想要这样做的一个原因是:

The standard behaviour for text boxes when they get focus is for the caret to be placed at the same position that it was when the control lost focus. If you would prefer throughout your application that when the user tabs to any textbox that the whole content of the textbox was highlighted then adding a simple handler in the resource dictionary would do the trick.

文本框获得焦点时的标准行为是将插入符号放置在控件失去焦点时的相同位置。如果您希望在整个应用程序中,当用户选择任何文本框时突出显示文本框的全部内容,那么在资源字典中添加一个简单的处理程序就可以解决问题。

Any other reason where you want the default user interaction behaviour to be different from the out of the box behaviour seems like good candidates for a code behind in a resource dictionary.

您希望默认用户交互行为与开箱即用行为不同的任何其他原因似乎都是资源字典中隐藏代码的良好候选者。

Totally agree that anything which is application functionality specific ought not be in a code behind of a resource dictionary.

完全同意任何特定于应用程序功能的东西都不应该出现在资源字典的代码后面。

回答by Gishu

XAML is for constructing object graphs not containing code.
A Data template is used to indicate how a custom user-object is to be rendered on screen... (e.g. if it is a listbox item) behavior is not part of a data template's area of expertise. Redraw the solution...

XAML 用于构建不包含代码的对象图。
数据模板用于指示如何在屏幕上呈现自定义用户对象...(例如,如果它是列表框项目)行为不是数据模板专业领域的一部分。重新绘制解决方案...