У меня есть кнопка внутри ControlTemplate. Как мне получить ссылку на это?
-
06-07-2019 - |
Вопрос
Я просто хочу включить или отключить кнопку внутри шаблона ControlTemplate для редактора WPF, который я использую.
Решение
Я согласен с Джоэлом в том, что предпочтительным методом было бы инициировать установку свойства Enabled кнопки с разметкой xaml либо с помощью триггера, либо путем привязки значения Enabled к другому свойству зависимости, возможно, с родительским элементом, вероятно, с помощью помощь ValueConverter.
Однако, если вам нужно сделать это явно в C #, вы можете использовать метод FindName () в свойстве шаблона кнопки. Существует MSDN , ссылка на которую приведена здесь .
Другие советы
Я рекомендую легко управлять кнопками с помощью команд RoutedUIC, включая их легкое включение и отключение. Команды не нуждаются в каких-либо ссылках на кнопку, поэтому это также решает вашу проблему.
Смотрите здесь:
<Window.CommandBindings>
<CommandBinding
Command="{x:Static local:MyCommands.MyCommand}"
Executed="CommandBinding_Executed"
CanExecute="CommandBinding_CanExecute" />
</Window.CommandBindings>
<Window.Resources>
<ControlTemplate x:Key="MyTemplate" TargetType="Label">
<Button Command="{x:Static local:MyCommands.MyCommand}">
<TextBlock>
Click Me
<TextBlock Text="{TemplateBinding Content}" />
</TextBlock>
</Button>
</ControlTemplate>
</Window.Resources>
<StackPanel>
<Label Template="{StaticResource MyTemplate}">1</Label>
<Label Template="{StaticResource MyTemplate}">2</Label>
<Label Template="{StaticResource MyTemplate}">3</Label>
<Label Template="{StaticResource MyTemplate}">4</Label>
<Label Template="{StaticResource MyTemplate}">5</Label>
</StackPanel>
Используйте это:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void CommandBinding_CanExecute(object sender, System.Windows.Input.CanExecuteRoutedEventArgs e)
{
// your logic here
int _Integer = -1;
int.TryParse(e.Parameter.ToString(), out _Integer);
e.CanExecute = _Integer % 2 == 0;
}
private void CommandBinding_Executed(object sender, System.Windows.Input.ExecutedRoutedEventArgs e)
{
// do something when clicked
}
}
public static class MyCommands
{
public static RoutedUICommand MyCommand = new RoutedUICommand();
}
Похоже:
Вы действительно не должны делать это явно, но вместо этого устанавливайте его с помощью триггеров в самом ControlTemplate
. Эти триггеры будут реагировать на некоторые другие изменения и будут устанавливать свойство Enabled
Button
.
У меня была проблема с кнопками в controlTemplates & amp; DataTemplates. Я нахожу, что триггеры часто слишком громоздки, чтобы предоставить именно то, что хотят мои клиенты, у меня оказалось слишком много конвертеров. Метод, который я впервые попробовал, заключался в том, чтобы определить эти более сложные шаблоны встроенными, чтобы они могли быть связаны с командами (& событиями codebehind) на моих экранах ViewModel.
если вы создаете свой собственный элемент управления, я должен упомянуть, что самый простой способ - просто назвать кнопку, а затем использовать что-то вроде этого:
hourHand = this.Template.FindName( "PART_HourHand", this ) as Rectangle;
Недавно, однако, я изменил тактику (обратно на отдельные файлы .. RE-USE!), но начал добавлять ViewModel (своего рода), к которому я добавляю суффикс ... TemplateCommandStore
ко всем моим шаблонам это становится немного сложным. Я даже использую это при составлении шаблонов своих пользовательских элементов управления (в основном для согласованности)
public class BookingDetailsTemplateCommandStore
{
public OpenWindowCommand_Command OpenWindowCommand_Command { get; set; }
public BookingDetailsTemplateCommandStore()
{
OpenWindowCommand_Command = new OpenWindowCommand_Command( this );
}
}
Затем я могу с радостью использовать эту команду в шаблоне. Вы также можете передать управляющие ссылки в хранилище команд, привязав к нему свойство (зависимость?) Для захвата событий & amp; более точный контроль над вашими шаблонами.
<DataTemplate DataType="{x:Type LeisureServices:BookingSummary}">
<Border Height="50" otherStyling="xyz">
<Border.Resources>
<local:BookingDetailsTemplateCommandStore x:Key="CommandStore" />
</Border.Resources>
<DockPanel>
<Button otherStyling="xyz"
Command="{Binding Source={StaticResource CommandStore},
Path=OpenWindowCommand_Command}" />
MVVM: Я считаю, что пока графическая логика только и полностью отличается от бизнес-логики, эта методология не мешает MVVM. По сути, я добавляю постоянную кодируемость C # к шаблонам, которую может пропустить любой, кто слишком много времени провел в winforms.