Можно ли установить код позади словаря ресурсов в WPF для обработки событий?

Можно ли установить код за словарь ресурсов в WPF. Например, в пользовательском контроле для кнопки вы объявляете ее в XAML. Код обработки события для нажатия кнопки выполняется в файле кода за элементом управления. Если бы я должен был создать шаблон данных с кнопкой, как я могу написать код обработчика события для его нажатия кнопки в словаре ресурсов.

5 ответов

Решение

Я думаю, что вы спрашиваете, что вы хотите файл с выделенным кодом для ResourceDictionary. Вы можете сделать это полностью! На самом деле, вы делаете это так же, как для окна:

Скажем, у вас есть ResourceDictionary под названием MyResourceDictionary. В вашем файле 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>

Я не согласен с "ageektrapped"... использование метода частичного класса не является хорошей практикой. Какова будет цель отделения словаря от страницы?

Из выделенного кода вы можете получить доступ к элементу a x:Name, используя:

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

Вы можете сделать это в методе OnApplyTemplate, если хотите подключиться к элементам управления при загрузке пользовательского элемента управления. OnApplyTemplate должен быть переопределен, чтобы сделать это. Это обычная практика и позволяет вашему стилю оставаться оторванным от контроля. (Стиль не должен зависеть от элемента управления, но элемент управления должен зависеть от наличия стиля).

Гишу - хотя это может показаться "практикой, не поощряемой". Вот одна из причин, по которой вы можете захотеть сделать это:

Стандартное поведение для текстовых полей, когда они получают фокус, заключается в том, что курсор помещается в то же положение, в котором он находился, когда элемент управления терял фокус. Если во всем приложении вы предпочитаете, чтобы, когда пользователь вкладывал в любое текстовое поле, было выделено все содержимое текстового поля, то добавление простого обработчика в словаре ресурсов помогло бы.

Любая другая причина, по которой вы хотите, чтобы поведение по умолчанию для взаимодействия с пользователем отличалось от стандартного поведения, кажется хорошим кандидатом для кода в словаре ресурсов.

Полностью согласен, что все, что специфично для функциональности приложения, не должно быть в коде позади словаря ресурсов.

Добавление ... в наши дни, с появлением {x:Bind ...}, если вы хотите поместить свой DataTemplate в общий файл ResourceDictionary, вам необходимо предоставить этому файлу код.

XAML предназначен для построения графов объектов, не содержащих код.
Шаблон данных используется для указания того, как пользовательский объект-объект должен отображаться на экране... (например, если это элемент списка), это не является частью области компетенции шаблона данных. Перерисовать решение...

Другие вопросы по тегам