J'ai un bouton dans un ControlTemplate. Comment puis-je obtenir une référence?

StackOverflow https://stackoverflow.com/questions/184871

  •  06-07-2019
  •  | 
  •  

Question

Je veux juste activer ou désactiver le bouton à l'intérieur d'un ControlTemplate pour un éditeur WPF que j'utilise.

Était-ce utile?

La solution

Je conviens avec Joel que la méthode recommandée consiste à déclencher le paramétrage de la propriété Enabled du bouton avec le balisage xaml, via un déclencheur ou en liant la valeur Enabled à une autre propriété de dépendance, éventuellement sur un élément parent, probablement avec le paramètre. aide d'un ValueConverter.

Toutefois, si vous devez le faire explicitement en C #, vous pouvez utiliser la méthode FindName () sur la propriété template du bouton. Il existe un lié ??à MSDN ici <.>.

Autres conseils

Il est recommandé de contrôler facilement les boutons au moyen des commandes RoutedUIC - notamment de les activer et les désactiver facilement. Les commandes n'ont besoin d'aucun type de référence au bouton, ce qui résout également votre problème.

Voir ici:

<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>

Utilisez ceci:

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();
}

Ressemble à:

capture d'écran

Vous ne devriez vraiment pas le faire explicitement, mais plutôt le définir avec des déclencheurs dans le ControlTemplate lui-même. Ces déclencheurs réagiraient à une autre modification et définiraient la propriété Enabled du bouton .

J'ai eu un problème avec les boutons de controlTemplates & amp; modèles de données. Je trouve que les déclencheurs sont souvent trop lourds pour fournir exactement ce que veulent mes clients, je me suis retrouvé avec trop de convertisseurs. La méthode que j’ai d'abord essayée consistait à définir ces modèles plus complexes en ligne afin qu'ils puissent être liés aux commandes (& événements codebehind) sur mes écrans ViewModel.

si vous modélisez votre propre contrôle, je devrais mentionner que la méthode la plus simple consiste à nommer simplement le bouton puis à utiliser quelque chose comme ceci:

hourHand   = this.Template.FindName( "PART_HourHand",   this ) as Rectangle;

Récemment cependant, j’ai changé de tact (retour à des fichiers indépendants .. RE-USE!), mais j’ai commencé à ajouter un ViewModel (sorte) que je suffixe ... TemplateCommandStore à tous mes modèles. ça devient un peu complexe. J'utilise même cela lors du gabarit de mes contrôles personnalisés (par souci de cohérence, principalement)

public class BookingDetailsTemplateCommandStore
{
    public OpenWindowCommand_Command OpenWindowCommand_Command { get; set; }

    public BookingDetailsTemplateCommandStore()
    {
        OpenWindowCommand_Command = new OpenWindowCommand_Command( this );
    }       
}

Je peux ensuite utiliser cette commande avec plaisir dans un modèle. Vous pouvez également passer des références de contrôle dans le magasin de commandes en lui liant une propriété (dépendance) pour capturer les événements & amp; Exercez un contrôle plus précis sur vos modèles.

<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: Je constate que, tant que la logique graphique n’est que cela, et complètement distincte de la logique métier, cette méthodologie n’interfère pas avec MVVM. En fait, j’ajoute aux modèles une capacité de code C # cohérente, que toute personne qui passerait trop de temps dans winforms pourrait manquer autant que moi.

scroll top