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


147

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


1
正确的方法是使用命令,它还使您能够启用和禁用按钮,同时您也可以通过一些答案表明它对我有帮助。
阿兰·穆赫兰

Answers:


209

我想您要问的是您想要ResourceDictionary的代码隐藏文件。您完全可以做到这一点!实际上,您可以使用与Window相同的方法来执行此操作:

假设您有一个称为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">

然后,使用以下声明在名为MyResourceDictionary.xaml.cs的文件后面创建代码:

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

这样就完成了。您可以将任何所需的代码放在后面:方法,属性和事件处理程序。

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

万一您正在使用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>

7
作为ageektrapped答案的附录:确保将代码的完全限定名称放在x:Class属性中。x:Class="MyCompany.MyProject.MySubFolder1.MyResourceDictionary"否则,如果仅输入x:Class =“ MyResourceDictionary”,则xaml解析器将找不到您的类。
09年

29
确保在后面的部分类代码中提供了默认构造函数,并确保它调用InitializeComponent()。(就我而言,我使用的是MEF来导出资源字典。)
Scott Whitlock,2009年

4
更新了代码段,以支持注释。我认为需要完成答案; 一个常见的错误。我刚才做的是:)如果您不喜欢它,请还原。感谢你的回答。
纪州2010年

2
请注意(至少在wp8.1中),此命令不再有效,您必须创建一个自定义用户控件,供您的资源字典引用
Jared

9
您还必须将ResourceDictionary的XAML文件上的Build Action设置为“ Page”,否则InitializeComponent()调用将无法编译。(默认情况下,ResourceDictionary XAML文件通常默认设置为“资源”。)
user1454265,2015年

9

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

在隐藏的代码中,您可以使用以下命令访问ax:Name元素:

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

如果要在自定义控件加载时连接到控件,可以在OnApplyTemplate方法中执行操作。为此,需要重写OnApplyTemplate。这是一种常见的做法,可以使您的样式与控件保持断开连接。(样式不应取决于控件,但控件应取决于具有样式)。


7
Phobis我认为从页面中分离出Dictionary的目的是关于xaml主页的可​​重用性和可读性。上述解决方案也对我有用。
cleftheris

5

Gishu-尽管这似乎是“通常不鼓励实践”,但是您可能想要这样做的原因之一是:

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

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

完全同意,任何特定于应用程序功能的内容都不应放在资源字典后面的代码中。


0

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


结论:您是否建议在代码后面使用资源dic?我怀疑我从未使用过它。
Shimmy Weitzhandler,2009年

1
我不会-对我来说感觉不对。字典应返回特定键的值。在OP的情况下,将代码与数据模板捆绑在一起。我宁愿尝试其他方法。例如使用Command模型。我需要有关OP问题的更多详细信息,以推荐差异解决方案。
Gishu 2009年

1
完全不同意。使用MVVM,在一种情况下,隐藏代码非常有用:开发附加属性。使它与后面的代码一起使用,然后将其移植到附加属性。这比简单地从头开始开发附加属性要快得多,除非您的大脑像曼哈顿一样大。
Contango 2015年
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.