In WPF, how do you tell if the left mouse button is currently down without using any events?

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

Pregunta

I have an app where I want to be able to move a slider. However, the slider is automatically updated by the program every 30 seconds. When I try to change the slider position with my mouse, the program is still updating the slider position, so I cannot move it manually with the mouse.

Somehow, I want the app to NOT update the slider if the user is in the process of changing its position. How can I tell if the left mouse button is down without using the left button down event? I just want to be able to access the mouse, and check the button state of the left mouse button. How do I access it without being inside of a mouse event?

¿Fue útil?

Solución

bool mouseIsDown = System.Windows.Input.Mouse.LeftButton == MouseButtonState.Pressed;

Otros consejos

Ok,

I figured it out. The Slider control in WPF does NOT fire the MouseDown, LeftMouseDown, or LeftMouseUp events. This is because it uses them internally to adjust the value as the user is manipulating the slider. However, the Slider control in WPF DOES fire the PreviewLeftMouseDown and the PreviewLeftMouseUp events. In addition, when you click the Left Mouse button, the Slider Control automatically captures the mouse and holds on to it until you release the Left Mouse button.

I was able to solve my problem with the following 3 events:

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

You may consider, in your case, using Mouse Class.

If I'm not mistaken it doesn't track the state of the button when the mouse goes out of the UI of the application, so to be sure that you have always correct information, you may need to capture mouse.

Repeat, you need to check this by yourself.

As I understand it, you want to keep an MVVM pattern to accomplish this task.

So first I would start by designing what I want in my 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();
    }
}

then you could use the Blend Interactivity library to do the UI side in xaml.

The following is an example. I don't know if the event name is correct. You could also do the same with mouse up and done editing.

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

Accepted answer didn't work for me, but this did:

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

There are some rare cases, where System.Windows.Input.Mouse.LeftButton does not work. For example during Resize.

Then you can use 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;
Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top