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

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

Ответ 1

Я думаю, что вы спрашиваете, хотите ли вы создать код для файла 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>

Ответ 2

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

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

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

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

Ответ 3

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

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

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

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

Ответ 4

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