Подтвердить что ты не робот

Как правильно наследовать пользовательский элемент управления, определенный в XAML в Silverlight

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

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

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

4b9b3361

Ответ 1

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

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

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

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

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

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

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

Ответ 2

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

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

Ответ 3

Как описывает ссылка Mihnea, самым простым решением является простое добавление пространства имен в ваш XAML:

С#

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>

Ответ 4

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

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