Это хорошая идея, чтобы смешать ControlTemplate с пользовательским контролем? - PullRequest
1 голос
/ 08 февраля 2009

Возможно ли и хорошая идея иметь пользовательский элемент управления (public MyControl: UserControl), который поддерживает как ControlTemplate s, так и существующий контент? Я понял, что ControlTemplate s следует использовать только тогда, когда вы наследуете от Control (public MyControl: Control), но я обнаружил, что вы можете использовать их также с UserControl, если ваш UserControl.xaml пуст.

Представьте, что у меня есть элемент управления, который имеет два прямоугольника рядом, как показано ниже:

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"> 
    <Grid ShowGridLines="true" Height="100" Width="100"> 
        <Grid.ColumnDefinitions> 
            <ColumnDefinition/> 
            <ColumnDefinition/> 
        </Grid.ColumnDefinitions> 
        <Rectangle Name="left" Grid.Column="0" Height="90" Fill="LightBlue"/> 
        <Rectangle Name="right" Grid.Column="1" Height="100" Fill="LightGreen"/> 
    </Grid> 
</Page> 

Я бы хотел, чтобы пользователь элемента управления мог заменить эти прямоугольники на те, которые он хочет использовать. Так что мне нужно ControlTemplate.

Но в 99% случаев пользователь элемента управления доволен существующей функциональностью, поэтому я хотел бы, чтобы он мог сказать:

Код:

mycontrol.Left.Fill = ....

XAML:

<mycontrol>
<mycontrol.Left.Fill = "Red"/>
</mycontrol>

Это кажется невозможным, поскольку, если я поддерживаю шаблоны управления, у меня действительно нет элементов пользовательского интерфейса или xaml. У меня есть только код файла. Я думаю, у меня может быть DependencyProperty Left, но пока у меня нет какого-то контейнера, который бы содержал содержимое, которое не принесло бы много пользы. Я должен был бы создать сетку в коде позади файла. Не кажется хорошей идеей.

И, наконец, я хотел бы иметь возможность использовать дженерики, чтобы пользователь мог указать тип деталей:

MyControl mycontrol<TLeft, TRight> = new MyControl<Rectangle, Button>();

Это поможет в коде из-за безопасности типов (нет необходимости приводить FrameworkElement к правильному типу). К сожалению, я не думаю, что дженерики действительно поддерживаются на стороне XAML.

Есть ли какое-либо решение этой проблемы или это действительно "Наследование от Control для поддержки ControlTemplate s, но потеря легкого удобства использования элемента управления. Наследование от UserControl для поддержки легкого использования, но потеря ControlTemplate поддержка "?

1 Ответ

2 голосов
/ 08 февраля 2009

Добавить свойство зависимости в элемент управления:

public static DependencyProperty LeftFillProperty = DependencyProperty.
   Register("LeftFill", typeof(Brush), typeof(MyControl));

public Brush LeftFill
{
   get { return (Brush)GetValue(LeftFillProperty); }
   set { SetValue(LeftFillProperty,value); }
}

Тогда в шаблоне управления по умолчанию используйте:

<Rectangle Name="left" Grid.Column="0" Height="90" Fill="{TemplateBinding LeftFill}"/>

Это оставит вас использовать (C #)

ctrl.LeftFill = Brushes.Red;

или (XAML)

<c:MyControl LeftFill="Red"/>

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

Кстати, вам следует рассмотреть возможность изменения имен с «левого» и «правого» на другое («MasterPanel» и «DetailPanel», «FoldersArea» и «FilesArea», независимо от логического использования в вашем элементе управления) решит вопрос о замене шаблона по умолчанию шаблоном, который отображает те же данные в другом макете (например, сверху и снизу вместо левого и правого).

...