Ho un pulsante all'interno di un ControlTemplate. Come posso ottenere un riferimento ad esso?
-
06-07-2019 - |
Domanda
Voglio solo abilitare o disabilitare il pulsante all'interno di un ControlTemplate per un editor WPF che sto usando.
Soluzione
Concordo con Joel sul fatto che il metodo preferito sarebbe innescare l'impostazione della proprietà Enabled del pulsante con markup xaml, tramite un trigger o legando il valore Enabled a un'altra proprietà di dipendenza, possibilmente su un elemento padre, probabilmente con il metodo aiuto di un ValueConverter.
Tuttavia, se è necessario farlo esplicitamente in C #, è possibile utilizzare il metodo FindName () sulla proprietà template del pulsante. C'è un MSDN "come" collegato qui .
Altri suggerimenti
Mio consiglio di controllare facilmente i pulsanti tramite i comandi RoutedUIC, incluso abilitarli e disabilitarli facilmente. I comandi non necessitano di alcun tipo di riferimento al pulsante, quindi anche questo risolve il tuo problema.
Vedi qui:
<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>
Usa questo:
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();
}
Sembra:
Non dovresti davvero farlo esplicitamente, ma invece impostalo con Trigger nel ControlTemplate
stesso. Questi trigger reagirebbero a qualche altra modifica e imposterebbero la proprietà Enabled
del pulsante
.
Ho avuto un problema con i pulsanti in controlTemplates & amp; DataTemplates. Trovo che i trigger siano spesso troppo ingombranti per fornire esattamente quello che vogliono i miei clienti, ho finito con troppi convertitori. Il metodo che ho provato per la prima volta è stato quello di definire questi modelli più difficili in linea in modo che potessero essere associati ai comandi (& amp; codebehind events) sui miei schermi ViewModel.
se stai modellando il tuo controllo, dovrei menzionare il metodo più semplice è semplicemente nominare il pulsante e usare qualcosa del genere:
hourHand = this.Template.FindName( "PART_HourHand", this ) as Rectangle;
Di recente, tuttavia, ho cambiato tatto (tornando ai file singoli ... RIUTILIZZA!) ma ho iniziato ad aggiungere un ViewModel (di sorta) che ho aggiunto ... TemplateCommandStore
a tutti i miei modelli diventa un po 'complesso. Lo uso persino quando modifico i miei controlli personalizzati (per coerenza, principalmente)
public class BookingDetailsTemplateCommandStore
{
public OpenWindowCommand_Command OpenWindowCommand_Command { get; set; }
public BookingDetailsTemplateCommandStore()
{
OpenWindowCommand_Command = new OpenWindowCommand_Command( this );
}
}
Posso quindi usare felicemente questo comando in un modello. Puoi anche passare i riferimenti di controllo nell'archivio comandi associando una proprietà (dipendenza?) Ad esso per acquisire eventi e amp; ottenere un controllo più preciso sui tuoi modelli.
<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: Trovo che fintanto che la logica grafica è proprio questa, e completamente distinta dalla logica aziendale, questa metodologia non interferisce con MVVM. In sostanza, aggiungo ai modelli modelli coerenti capacità di codice C #, che chiunque perderebbe troppo tempo in Winforms potrebbe perdere quanto me.