Чтобы ответить на ваш последний вопрос: НЕТ. Элемент управления без внешнего вида не должен требовать какого-либо известного XAML. Вот что значит безликий.
У вас есть несколько вариантов здесь, но я бы порекомендовал обернуть ваши элементы в кнопки с практически пустым шаблоном управления:
<ControlTemplate x:Key="contentOnlyButton" TargetType="{x:Type Button}">
<ContentPresenter />
</ControlTemplate>
...
<Button Grid.Column="0" Template="{StaticResource contentOnlyButton}"
Command="{x:Static local:LooklessControl.PrevItemCommand}">
<Path x:Name="pathLeftArrow" Data="M0,0.5 L1,1 1,0Z" Width="6" Height="14"
Stretch="Fill" HorizontalAlignment="Center" Fill="SlateBlue"/>
</Button>
Ваш другой вариант (и я бы сказал, что это, вероятно, не то, что вы должны делать для выполнения команд на щелчках, но может быть применим в других обстоятельствах), это искать именованную часть в вашем шаблоне в OnApplyTemplate и подключать до событий.
public override void OnApplyTemplate()
{
var prevElement = this.GetTemplateChild("PART_PathLeftArrow") as UIElement;
if (prevElement != null)
prevElement.MouseDown += (o, e) => PrevItemHandler();
...
}
При этом следует отметить, что шаблон не обязателен для определения частей, которые вы ищете, поэтому вам необходимо тщательно проверить это обстоятельство. Если вы выберете NullReferenceExceptions
, то рестайлинг вашего контроля станет настоящей болью для дизайнеров / разработчиков, которые случайно удалили необходимый элемент. Вы также захотите придерживаться стандартной практики именования необходимых элементов с помощью синтаксиса PART_ и украшения своего класса атрибутами TemplatePart
.
[TemplatePart(Name = "PART_PathLeftArrow", Type = typeof(UIElement))]
[TemplatePart(Name = "PART_PathRightArrow", Type = typeof(UIElement))]
...
public class LooklessControl : Control
Редактировать: Для того, чтобы кнопки реагировали на щелчки, вам необходимо настроить привязки команд к вашим функциям, которые вы уже определили. Вы бы сделали это как привязку команды класса следующим образом:
static LooklessControl()
{
CommandManager.RegisterClassCommandBinding(
typeof(LooklessControl),
new CommandBinding(NextItemCommand, ExecutedNextItemCommand, CanExecuteNextItemCommand));
CommandManager.RegisterClassCommandBinding(
typeof(LooklessControl),
new CommandBinding(PrevItemCommand, ExecutedPrevItemCommand, CanExecutePrevItemCommand));
}
Причина связывания команды класса заключается в том, что если вы добавите ее в коллекцию CommandBindings вашего элемента управления, кто-то, использующий ваш элемент управления, может непреднамеренно удалить их. Также не забудьте обновить методы обработки команд, чтобы иметь статическую семантику.