ControlTemplate内にボタンがあります。それへの参照を取得するにはどうすればよいですか?
-
06-07-2019 - |
質問
使用しているWPFエディターのControlTemplate内のボタンを有効または無効にするだけです。
解決
優先的な方法は、トリガーを使用するか、おそらくは親要素の別の依存関係プロパティにEnabled値をバインドすることにより、xamlマークアップを使用してボタンのEnabledプロパティの設定をトリガーすることです。 ValueConverterのヘルプ。
ただし、C#で明示的に行う必要がある場合は、ボタンのテンプレートプロパティでFindName()メソッドを使用できます。 MSDNの「方法」ここにリンクがあります。
他のヒント
My RoutedUICommandsを使用して、ボタンを簡単に制御することをお勧めします(簡単に有効化および無効化することを含む)。コマンドはボタンへの参照を必要としないため、問題も解決します。
こちらをご覧ください:
<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
自体でTriggersを使用して設定する必要があります。これらのトリガーは他の変更に反応し、 Button
の Enabled
プロパティを設定します。
controlTemplates&amp;のボタンに問題がありました。 dataTemplates。トリガーは、クライアントが望むものを正確に提供するには面倒であることが多いので、コンバーターが多すぎることになりました。私が最初に試した方法は、これらのより難しいテンプレートをインラインで定義して、画面のViewModelのコマンド(&amp; codebehindイベント)にバインドできるようにすることでした。
独自のコントロールをテンプレート化する場合、最も簡単な方法はボタンに名前を付けてから次のようなものを使用することです:
hourHand = this.Template.FindName( "PART_HourHand", this ) as Rectangle;
しかし、最近、タクトを変更しました(個々のファイルに戻りました。再利用!)が、すべてのテンプレートに ... TemplateCommandStore
のサフィックスを付けたViewModelを追加し始めました。それは少し複雑になります。カスタムコントロールをテンプレート化するときにも使用します(ほとんどの場合、一貫性のため)
public class BookingDetailsTemplateCommandStore
{
public OpenWindowCommand_Command OpenWindowCommand_Command { get; set; }
public BookingDetailsTemplateCommandStore()
{
OpenWindowCommand_Command = new OpenWindowCommand_Command( this );
}
}
その後、テンプレートでこのコマンドを喜んで使用できます。また、(依存関係?)プロパティをコントロールにバインドしてイベントをキャプチャすることにより、コントロール参照をコマンドストアに渡すことができます。テンプレートをより正確に制御できます。
<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#コード機能を追加します。これは、winformで時間を費やしすぎた人が私と同じくらい見逃す可能性があります。