Как правильно наследовать от пользовательского контроля, определенного в XAML в Silverlight - PullRequest
17 голосов
/ 22 октября 2008

Если у меня есть пользовательский контроль (в Silverlight), который я написал, который использует XAML для определения его внешнего вида, как я могу сделать его настроенную версию?

т.е. У меня есть MyControl.xaml & MyControl.xaml.cs

Что мне нужно делать, если я хочу дочерний класс "SpecialisedControl"? Я предполагаю, что я просто создаю новый файл кода, а затем наследую от MyControl. Но что, если я хочу изменить внешний вид базового класса - что мне делать?

Ответы [ 4 ]

8 голосов
/ 22 октября 2008

Я написал это, думая, что вы говорите о WPF, а не о Silverlight, но может быть достаточно совпадений, чтобы это было полезно, поэтому я все равно публикую это.

Если под «изменить внешний вид базового класса» вы подразумеваете «предоставить новый шаблон», то, вероятно, вам нужен CustomControl, а не UserControl.

Лучший способ сделать это - следовать примеру, заданному другими элементами управления Microsoft, такими как Button или ListBox:

  1. Создайте класс, производный непосредственно от Control (или того, что ближе всего к вашему контролю).
  2. Если какие-либо свойства должны быть доступны элементу управления (например, текст на кнопке), убедитесь, что вы правильно определили их как DependencyProperties.
  3. Как описано здесь , создайте ResourceDictionary под названием Themes / generic.xaml и добавьте стиль для своего класса, который включает в себя шаблон (не назначайте стилю ключ).
  4. Используйте TemplateBindings для любых свойств элементов вашего элемента управления, которым необходимо получить значения из вашего элемента управления.
  5. Если вам нужно прикрепить какие-либо обработчики событий к элементам в вашем шаблоне, присвойте им уникальное имя. Microsoft использует соглашение, заключающееся в добавлении префиксов к этим именам "PART_", и я думаю, что это хорошо для согласованности, но это не является строго обязательным.
  6. Опять же, если вам нужно присоединить обработчики событий, перегрузите OnApplyTemplate (). В этом методе вы должны отсоединить любые старые обработчики событий (мы, конечно, не хотим утечек памяти!) И искать элементы с именами, указанными вами в шаблоне - когда вы их найдете, присоедините обработчики событий, если это необходимо .

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

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

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

5 голосов
/ 24 июня 2010

Как описывает ссылка Михни, самое простое решение - просто добавить пространство имен в свой XAML:

C #

public class MyBase : UserControl
{
}

public class FirstUserControl : MyBase
{
...
}

XAML

<local:MyBase 
    x:Class="FirstUserControl" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:local="YourAssembly" ...>

    <!-- Sticking with UserControl instead of local:MyBase makes this clearer -->
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                ..
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>

..Your XAML
</local:MyBase>
5 голосов
/ 11 февраля 2009

Я не знаю, мне нравится делать вещи с простыми объектами. Вот статья, в которой описывается простой способ вывести элемент управления, разработанный в XAML, за пределы иерархии наследования, чтобы можно было настроить внешний вид и поведение с помощью SimpleThingsLikeInheritance, а не MicrosoftStuffThatAlmostWorks

http://gen5.info/q/2009/02/10/subverting-xaml-how-to-inherit-from-silverlight-user-controls/

0 голосов
/ 06 марта 2009

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

В этом посте я объясню, как вы реализуете эти два метода. http://www.lab101.be/2008/07/silverlight-usercontrol-inheritance/

...