Question

Je vais avoir des problèmes avec l'EventToCommand ne se comporte pas comme je me attends avec CaptureMouse.

J'ai ResizeGrip que j'ai défini plusieurs années EventToCommand sur:

<ResizeGrip Name="ResizeGrip" HorizontalAlignment="Right" VerticalAlignment="Bottom" Cursor="SizeNWSE">
<i:Interaction.Triggers>
  <i:EventTrigger EventName="MouseLeftButtonDown">
   <cmd:EventToCommand Command="{Binding ResizeStartCommand}" PassEventArgsToCommand="True" />
  </i:EventTrigger>
  <i:EventTrigger EventName="MouseLeftButtonUp">
   <cmd:EventToCommand Command="{Binding ResizeStopCommand}" PassEventArgsToCommand="True" />
  </i:EventTrigger>
  <i:EventTrigger EventName="MouseMove">
   <cmd:EventToCommand Command="{Binding ResizeCommand}" PassEventArgsToCommand="True" />
  </i:EventTrigger>
 </i:Interaction.Triggers>
 </ResizeGrip>

Les fonctions de gestion sont définies dans le constructeur de la classe:

ResizeStartCommand = new RelayCommand<MouseButtonEventArgs>(
    (e) => OnRequestResizeStart(e));
ResizeStopCommand = new RelayCommand<MouseButtonEventArgs>(
    (e) => OnRequestResizeStop(e));
ResizeCommand = new RelayCommand<MouseEventArgs>(
    (e) => OnRequestResize(e),
    param => CanResize);

Et enfin, je fais tout ma logique à redimensionner:

void OnRequestResizeStart(MouseButtonEventArgs e)
{
    bool r = Mouse.Capture((UIElement)e.Source);
    Console.WriteLine("mouse down: " + r.ToString());
}
void OnRequestResizeStop(MouseButtonEventArgs e)
{
    ((UIElement)e.Source).ReleaseMouseCapture();
    _canResize = false;
}
void OnRequestResize(MouseEventArgs e)
{
    Console.WriteLine("mouse move");
}
bool CanResize
{ get { return _canResize; } }

Les commandes OnRequestResizeStart et OnRequestResizeStop fonctionnent très bien, et le OnRequestResize fonctionne ... mais seulement quand je suis en fait sur la ResizeGrip. Il ne semble pas que le CaptureMouse n'envoie en fait tous les événements de la souris à l'ResizeGrip.

Est-ce une limitation du EventToCommand, ou fait quelque chose de besoin particulier de se produire?

Merci pour toute aide!

Était-ce utile?

La solution

Pourquoi utilisez-vous des commandes pour cette place de gestionnaires d'événements standards? Ceci est clairement la logique interface utilisateur qui appartient au code-behind, pas ViewModel.

**** Mise à jour **

Dans le cas où vous utilisez cela dans un ControlTemplate vous pouvez traiter le code du contrôle que votre code-behind. Pour ce faire, les connexions des événements que vous pouvez utiliser le modèle de TemplatePart et se connecter à l'élément spécialement nommé dans OnApplyTemplate. Afin de faciliter la fourniture de la taille (ou tout ce que vos besoins VM) vous pouvez ajouter un DP pour stocker la valeur appropriée et lier une propriété VM à cela. Cela permet également de faire deux de manière contraignante si vous avez besoin de faire quelque chose comme définir une taille initiale de la machine virtuelle.

// this doesn't enforce the name but suggests it
[TemplatePart(Name = "PART_Resizer", Type = typeof(ResizeGrip))]
public class MyContainer : ContentControl
{
    private ResizeGrip _grip;

    public static readonly DependencyProperty ContainerDimensionsProperty = DependencyProperty.Register(
        "ContainerDimensions",
        typeof(Size),
        typeof(MyContainer),
        new UIPropertyMetadata(Size.Empty, OnContainerDimensionsChanged));

    private static void OnContainerDimensionsChanged(DependencyObject dObj, DependencyPropertyChangedEventArgs e)
    {
        MyContainer myContainer = dObj as MyContainer;
        if (myContainer != null)
        {
            Size newValue = (Size)e.NewValue;
            if (newValue != Size.Empty)
            {
                myContainer.Width = newValue.Width;
                myContainer.Height = newValue.Height;
            }
        }
    }

    public Size ContainerDimensions
    {
        get { return (Size)GetValue(ContainerDimensionsProperty); }
        set { SetValue(ContainerDimensionsProperty, value); }
    }

    static MyContainer()
    {
        DefaultStyleKeyProperty.OverrideMetadata(typeof(MyContainer), new FrameworkPropertyMetadata(typeof(MyContainer)));
    }

    public override void OnApplyTemplate()
    {
        _grip = Template.FindName("PART_Resizer", this) as ResizeGrip;
        if (_grip != null)
        {
            _grip.MouseLeftButtonDown += Grip_MouseLeftButtonDown;
            // other handlers
        }

        SizeChanged += MyContainer_SizeChanged;
        base.OnApplyTemplate();
    }

    void MyContainer_SizeChanged(object sender, SizeChangedEventArgs e)
    {
        // update your DP
    }
    ...
}

Pour utiliser cela, vous devez vous assurer que vous avez un élément dans votre modèle avec le droit type et le nom pour correspondre à l'attribut.

<local:MyContainer ContainerDimensions="{Binding Path=SavedSize}">
    <local:MyContainer.Template>
        <ControlTemplate TargetType="{x:Type local:MyContainer}">
            <Grid>
                <Border Background="{TemplateBinding Background}">
                    <ContentPresenter/>
                </Border>
                <ResizeGrip x:Name="PART_Resizer" HorizontalAlignment="Right" VerticalAlignment="Bottom"
                            Width="20" Height="20"/>
            </Grid>
        </ControlTemplate>
    </local:MyContainer.Template>
</local:MyContainer>

Vous pouvez maintenant mettre ce modèle partout car il est ne déclarant pas des gestionnaires d'événements et est donc indépendant d'un fichier code-behind. Vous avez maintenant tous de votre logique de l'interface utilisateur encapsulé dans une classe spécifique de l'interface utilisateur, mais peut encore accéder aux données dont vous avez besoin dans votre VM en le liant.

Si vous pensez à ce sujet c'est la façon dont vous interagissez normalement avec commandes intégrées. Si vous utilisez un expandeur vous ne voulez pas passer clics de ToggleButton dans votre machine virtuelle et essayer de faire le contrôle développer à partir de là, mais vous voudrez peut-être savoir si l'extension est ouvert ou fermé, donc il y a une propriété IsExpanded que vous peut se lier à et sauvegarder et charger des données.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top