Как в WPF узнать, не нажата ли левая кнопка мыши, без каких-либо событий?

У меня есть приложение, в котором я хочу перемещать слайдер. Однако ползунок автоматически обновляется программой каждые 30 секунд. Когда я пытаюсь изменить положение ползунка с помощью мыши, программа все еще обновляет положение ползунка, поэтому я не могу перемещать его вручную с помощью мыши.

Почему-то я хочу, чтобы приложение НЕ обновляло ползунок, если пользователь меняет свое положение. Как я могу определить, нажата ли левая кнопка мыши, не используя событие нажатия левой кнопки? Я просто хочу иметь доступ к мыши и проверять состояние левой кнопки мыши. Как мне получить к нему доступ, не находясь внутри события мыши?


person Curtis    schedule 18.04.2013    source источник
comment
Почему вы не хотите использовать событие? Вы можете просто установить там флаг и запросить этот флаг перед обновлением.   -  person Daniel Hilgarth    schedule 18.04.2013
comment
Я пробовал события MouseLeftButtonDown и MouseLeftButtonUp, и они так и не сработали. При дальнейших исследованиях я обнаружил, что ползунок поглощает эти события и никогда не запускает их. Итак, после некоторых экспериментов и поисков я обнаружил, что могу просто использовать вместо них методы PreviewMouseLeftButtonDown и Up. Они делают то, что мне нужно. Я разместил приведенный ниже код в качестве ответа на этот пост. Спасибо, что указали мне правильное направление. Я поставил вам точку.   -  person Curtis    schedule 18.04.2013


Ответы (6)


Ok,

Я понял. Элемент управления Slider в WPF НЕ запускает события MouseDown, LeftMouseDown или LeftMouseUp. Это потому, что он использует их внутри для регулировки значения, когда пользователь манипулирует ползунком. Однако элемент управления Slider в WPF ДЕЙСТВИТЕЛЬНО запускает события PreviewLeftMouseDown и PreviewLeftMouseUp. Кроме того, когда вы щелкаете левой кнопкой мыши, ползунок автоматически захватывает мышь и удерживает ее, пока вы не отпустите левую кнопку мыши.

Я смог решить свою проблему с помощью следующих трех событий:

   private void _sliderVideoPosition_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        _adjustingVideoPositionSlider = true;
        _mediaElement.Pause();
    }

    private void _sliderVideoPosition_PreviewMouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        _adjustingVideoPositionSlider = false;
        _mediaElement.Play();
    }

    private void _sliderVideoPosition_ValueChanged(object sender, RoutedPropertyChangedEventArgs<double> e)
    {
        if (_adjustingVideoPositionSlider)
        {
            _mediaElement.Position = TimeSpan.FromMilliseconds((int)e.NewValue);
        }
    }
person Curtis    schedule 18.04.2013
comment
@JasonMassey Да, ему нужно подождать 2 дня, чтобы принять свой ответ. - person Nick Freeman; 19.04.2013
comment
Замечание: мне никогда не нравится использовать конструктор TimeSpan. Я ненавижу считать, сколько параметров нужно, чтобы понять, что это значит. TimeSpan.FromMilliseconds((int)e.NewValue) немного более очевиден. - person Nick Freeman; 19.04.2013


Насколько я понимаю, вы хотите сохранить шаблон MVVM для выполнения этой задачи.

Итак, сначала я бы начал с разработки того, что я хочу, в моей ViewModel.

public class ViewModel
{
    public ICommand EditingSliderCommand { get; set; } // actually set the command
    public ICommand DoneEditingCommand { get; set; } // actually set the command
    public bool IsEditing { get; set; }

    ...

    private void AutomaticUpdate
    {
        if (IsEditing)
            return;
        Update();
    }
}

тогда вы можете использовать библиотеку Blend Interactivity для создания пользовательского интерфейса в xaml.

Ниже приводится пример. Я не знаю, правильное ли название мероприятия. Вы также можете сделать то же самое, подняв мышку и завершив редактирование.

<i:Interaction.Triggers>
    <i:EventTrigger EventName="MouseDown">
        <cmd:EventToCommand Command="{Binding Mode=OneWay, 
                            Path=EditingSliderCommand}"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
person Nick Freeman    schedule 18.04.2013

Принятый ответ у меня не сработал, но вот такой:

if ((System.Windows.Forms.Control.MouseButtons & System.Windows.Forms.MouseButtons.Left) == System.Windows.Forms.MouseButtons.Left)
{
    System.Diagnostics.Debug.WriteLine("Left mouse down");
}
person Starwave    schedule 21.04.2021

Бывают редкие случаи, когда System.Windows.Input.Mouse.LeftButton не работает. Например во время изменения размера.

Затем вы можете использовать GetKeyState:

public enum VirtualKeyCodes : short
{
  LeftButton = 0x01
}

[DllImport("user32.dll")]
private static extern short GetKeyState(VirtualKeyCodes code);

public static bool CheckKey(VirtualKeyCodes code) => (GetKeyState(code) & 0xFF00) == 0xFF00;
person oleh    schedule 21.06.2021

person    schedule
comment
Именно то, что я искал. Просто, легко и не нужно слушать какие-либо события. - person christoph; 26.08.2015