web-dev-qa-db-fra.com

wpf reliure de gestionnaire d'événements en style

J'ai un style et je veux lier une commande à la variable EventSetter's Handler with RelativeSource. La commande est dans le viewModel.

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <EventSetter Event="MouseLeftButtonDown" 
                 Handler="{Binding TextBlockMouseLeftButtonDownCommand, 
                           RelativeSource={RelativeSource Self}}"/>
</Style>

Le problème est que je reçois une erreur, parce que quelque chose ne va pas avec cela (peut-être n'est-il pas possible de le faire aussi facilement)

J'ai déjà beaucoup cherché sur Google et j'ai trouvé la AttachedCommandBehaviour, mais je pense que cela ne fonctionne pas avec le style.

Pourriez-vous donner des conseils sur la façon de résoudre ce problème?

Mise à jour 13/10/2011

J'ai trouvé cela dans l'exemple de programme MVVM Light EventToCommand:

        <Button Background="{Binding Brushes.Brush1}"
            Margin="10"
            Style="{StaticResource ButtonStyle}"
            Content="Simple Command"
            Grid.Row="1"
            ToolTipService.ToolTip="Click to activate command">
        <i:Interaction.Triggers>
            <i:EventTrigger EventName="Click">
                <cmd:EventToCommand Command="{Binding SimpleCommand}" />
            </i:EventTrigger>
            <i:EventTrigger EventName="MouseLeave">
                <cmd:EventToCommand Command="{Binding ResetCommand}" />
            </i:EventTrigger>
        </i:Interaction.Triggers>
    </Button>

Mais ici, la reliure n'est pas dans le style. Comment puis-je mettre cette EventToCommand dans le style du bouton?

17
Zoltán Barna

À l'heure actuelle, vous liez l'événement MouseLeftButtonDown à TextBlock.TextBlockMouseLeftButtonDownCommand. TextBlockMouseLeftButtonDownCommand n'est pas une propriété valide pour un TextBlock, ni ne ressemble à un gestionnaire d'événements.

J'utilise le AttachedCommandBehavior tout le temps dans les styles pour relier une commande à un événement. La syntaxe ressemble généralement à ceci (notez la DataContextdans la liaison de commande):

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <Setter Property="local:CommandBehavior.Event" Value="MouseLeftButtonDown" />
    <Setter Property="local:CommandBehavior.Command"
            Value="{Binding DataContext.TextBlockMouseLeftButtonDownCommand, 
                            RelativeSource={RelativeSource Self}}" />
</Style>

L'alternative consiste à relier l'EventSetter à un événement du code-behind et à traiter la commande à partir de là:

<Style x:Key="ItemTextBlockEventSetterStyle" TargetType="{x:Type TextBlock}">
    <EventSetter Event="MouseLeftButtonDown" 
                 Handler="TextBlockMouseLeftButtonDown"/>
</Style>

Gestionnaire d'événements dans le code derrière ...

void TextBlockMouseLeftButtonDown(object sender, MouseEventArgs e)
{
    var tb = sender as TextBlock;
    if (tb != null)
    {
        MyViewModel vm = tb.DataContext as MyViewModel;

        if (vm != null && TextBlockMouseLeftButtonDownCommand != null
            && TextBlockMouseLeftButtonDownCommand.CanExecute(null))
        {
            vm.TextBlockMouseLeftButtonDownCommand.Execute(null)
        }
    }
}
22
Rachel

Comme vous utilisez MVVM, je vous suggère Galasoft MVVM Light ToolkitEventToCommand

3
Philippe Lavoie

Ma réponse sur cette question fait le travail sans outils/bibliothèques externes. Cependant, il n'utilise pas RelativeSource et ce n'est pas 100% MVVM. Il nécessite une ligne de code dans un gestionnaire d'événements code-behind.

0
Micah Vertal