Eu tenho um botão dentro de um ControlTemplate. Como faço para obter uma referência a ele?

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

  •  06-07-2019
  •  | 
  •  

Pergunta

Eu só quero ativar ou desativar o botão dentro de um ControlTemplate para um Editor de WPF que eu estou usando.

Foi útil?

Solução

Eu concordo com Joel que o método preferido seria para acionar a definição de propriedade Enabled do botão com marcação XAML, seja através de um gatilho ou ligando o valor activado para outra propriedade de dependência, possivelmente em um elemento pai, provavelmente com o ajuda de um ValueConverter.

No entanto, se você tem que fazê-lo explicitamente no C #, você pode usar o método FindName () na propriedade de modelo do botão. Há um MSDN 'como' ligados aqui .

Outras dicas

O meu eu recomendo que os botões são facilmente controlado através RoutedUICommands - incluindo ativação e desativação-los facilmente. Comandos não precisa de nenhum tipo de referência ao botão de modo Isto resolve o seu problema, também.

Veja aqui:

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

Use esta:

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

aparência:

Captura de tela

Você realmente não deveria estar fazendo isso explicitamente, mas em vez disso ser defini-lo com Triggers no próprio ControlTemplate. Esses gatilhos seriam reagindo a alguma outra mudança, e que defina a propriedade Enabled do Button.

Eu tive um problema com botões em ControlTemplates & DataTemplates. Acho gatilhos são muitas vezes demasiado pesado para fornecer exatamente o que meus clientes querem, eu acabei com muitos conversores. O método que eu tentei primeiro foi definir esses modelos mais difíceis em linha para que eles pudessem ser ligado a comandos (& eventos CodeBehind) em minhas telas ViewModel.

Se você está templates seu próprio controle, devo mencionar o método mais fácil é simplesmente o nome do botão, em seguida, usar algo como isto:

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

Recentemente, no entanto, eu mudei tato (de volta para arquivos indevidual .. RE-USE!), Mas começou a adição de um ViewModel (do tipo) que eu sufixo ...TemplateCommandStore a todos os meus modelos que ficam um pouco complexa. Eu até usar isso quando templates meus CustomControls (para a consistência, principalmente)

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

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

Posso, então, felizmente usar este comando em um modelo. Você também pode passar referências de controle para o armazenamento de comando através da ligação a (dependência?) Propriedade para que a eventos de captura e controle de consumo mais preciso sobre seus modelos.

<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: eu acho que, enquanto a lógica gráfica é apenas isso, e completamente distinta da lógica de negócios, esta metodologia não interfere com MVVM. Em essência, eu adicionar C # código-capacidade consistente para Templates, que qualquer um que passou muito tempo em winforms pode perder tanto quanto eu.

Licenciado em: CC-BY-SA com atribuição
Não afiliado a StackOverflow
scroll top