Чи можна встановити код за словником ресурсів у WPF для обробки подій?


147

Чи можна встановити код за словником ресурсів у WPF. Наприклад, у користувальницькому контролі для кнопки ви оголошуєте її в XAML. Код обробки події для натискання кнопки виконується у файлі коду, що знаходиться за контролем. Якщо я мав би створити шаблон даних за допомогою кнопки, як я можу написати код обробника подій для його натискання на кнопку в словнику ресурсів.


1
Правильний спосіб зробити це - використовувати команду, вона також дає вам можливість увімкнути та вимкнути кнопку, тоді як ви можете це зробити так, як деякі відповіді запропонували мені пахнути мені злому.
Aran Mulholland

Відповіді:


209

Я думаю, що ти запитуєш, чи хочеш ти файл із кодом для 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>

7
Як додаток до відповіді ageektrapped: Переконайтеся, що ви ввели атрибут x: Class повністю кваліфікованого імені вашого коду, що знаходиться за класом. x:Class="MyCompany.MyProject.MySubFolder1.MyResourceDictionary"В іншому випадку, якщо ви просто помістите x: Class = "MyResourceDictionary", аналізатор xaml не знайде вашого класу.
бадьорість

29
Переконайтеся, що ви надаєте конструктор за замовчуванням у коді часткового класу позаду та переконайтеся, що він викликає InitializeComponent (). (У моєму випадку я використовував MEF для експорту словника ресурсів.)
Скотт Вітлок

4
Оновлений фрагмент коду для більш високого коментаря. Я відчував, що потрібно виконати відповідь; поширена помилка. Я це зробив тільки зараз :) Поверніться, якщо вам це не подобається. Дякую за відповідь.
Гішу

2
Зауважте, що (принаймні в wp8.1) це більше не дійсно, і вам доведеться створити користувацький керування користувачами, що ваші посилання на джерела ресурсів
Jared

9
Вам також доведеться встановити Дію збірки у файлі XAML ResourceDictionary на "Сторінка", інакше виклик InitializeComponent () не буде компілюватися. (Файли XAML ResourceDictionary за замовчуванням зазвичай встановлені на "Resource".)
user1454265

9

Я не погоджуюся з "ageektrapped" ... використання методу часткового класу не є хорошою практикою. Яка була б мета відокремити Словник від сторінки тоді?

З коду позаду, ви можете отримати доступ до елемента: Ім'я за допомогою:

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

Ви можете зробити це в OnApplyTemplate метод , якщо ви хочете , щоб Підведення до елементів управління , коли ваші навантаження для користувача елементів управління. Для цього потрібно змінити OnApplyTemplate. Це звичайна практика і дозволяє вашому стилю залишатися відключеним від контролю. (Стиль не повинен залежати від елемента керування, але контроль повинен залежати від наявності стилю).


7
Фобіс Я думаю, що мета відокремлення словника від сторінки полягає у використанні та читанні xaml на головній сторінці. Вищевказане рішення працювало і для мене.
cleftheris

5

Gishu - хоча це може здатися "загалом не варто заохочувати практику". Ось одна причина, яку ви можете зробити це:

Стандартна поведінка для текстових полів, коли вони отримують фокус, полягає в тому, щоб карету розміщували в тому самому положенні, яке було, коли керування втрачало фокус. Якщо ви хочете, щоб у вашій програмі, коли користувач вклав будь-яку текстову скриньку, щоб було виділено весь вміст текстового поля, тоді додавання простого обробника в словник ресурсів зробить свою справу.

Будь-яка інша причина, коли ви хочете, щоб поведінка взаємодії користувачів за замовчуванням відрізнялася від поведінки поза рамками, здається, хороші кандидати для коду, що знаходиться в словнику ресурсів.

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


0

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


висновок: Чи рекомендуєте ви використовувати дик ресурсів з кодом позаду чи ні ?? Я ніколи його не використовував, я сумніваюся.
Шиммі Вайцхандлер

1
Я б не став - мені це не вірно. Словник повинен повертати значення для конкретних ключів. У випадку з ОП, поєднання коду з шаблоном даних .. Я б скоріше спробував інший підхід .. використовувати, наприклад, модель Command. Мені потрібно більше подробиць щодо проблеми ОП, щоб рекомендувати різні рішення.
Gishu

1
Повністю не згоден. З MVVM існує один сценарій, коли наявність коду позаду надзвичайно корисно: розробка доданих властивостей. Дозвольте йому працювати з кодом позаду, а потім перенесіть його на додану властивість. Це набагато швидше, ніж просто розробляти додану властивість з нуля, якщо у вас немає мозку розміром з Манхеттена.
Контанго
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.