Событие MouseUp не запускается, когда эллипс находится на границах холста - PullRequest
0 голосов
/ 21 марта 2020

Я создаю приложение, которое отображает подвижный джойстик. Джойстик можно свободно перемещать в пределах (внешних) границ холста (т. Е. Его Width и Height), используя события MouseDown, MouseMove и MouseUp.

Как вы можете видеть в коде C# для MouseUp джойстик должен вернуться в центр.

Однако, иногда, когда джойстик расположен непосредственно на границе холста (представлен периметром внешнего Ellipse, он не возвращается в центр. Фактически, MouseUp просто не стреляет.

Почему MouseUp не стреляет?

PS - я уменьшил мой код XAML для простых форм (внешний эллипс, представляющий основание джойстика, и внутренний эллипс, представляющий сам джойстик).

XAML:

<Window x:Class="MyApp.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:MyApp"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800" >
    <Grid>
        <Canvas  x:Name="Base" Margin="0" Width="340" Height="340">
            <Ellipse HorizontalAlignment="Left" Height="340" VerticalAlignment="Top" Width="340">
               <Ellipse.Fill>
                   <RadialGradientBrush>
                       <GradientStop Color="#FF2C2A2A" Offset="1" />
                       <GradientStop Color="#FF3A3737" />
                   </RadialGradientBrush>
               </Ellipse.Fill>
            </Ellipse>
            <Canvas  x:Name="Knob" VerticalAlignment="Top" HorizontalAlignment="Left" Width="0" Height="0" RenderTransformOrigin="0.5,0.5" Canvas.Left="125" Canvas.Top="125" MouseDown="Knob_MouseDown" MouseMove="Knob_MouseMove" MouseUp="Knob_MouseUp">
                <Ellipse HorizontalAlignment="Left" Height="90" VerticalAlignment="Top" Width="90" RenderTransformOrigin="0.5,0.5" Canvas.Top="1">
                    <Ellipse.Fill>
                        <RadialGradientBrush>
                            <GradientStop Color="#FF8A8A8A" />
                            <GradientStop Color="#FF979797" Offset="1" />
                        </RadialGradientBrush>
                    </Ellipse.Fill>
                </Ellipse>
                <Canvas.RenderTransform>
                    <TranslateTransform x:Name="knobPosition" />
                </Canvas.RenderTransform>
                <Canvas.Resources>
                    <Storyboard x:Key="CenterKnob" Name="centerKnob" Completed="centerKnob_Completed">
                        <DoubleAnimation Storyboard.TargetName="knobPosition"
                             Storyboard.TargetProperty="X" To="0" Duration="0:0:0.2">
                            <DoubleAnimation.EasingFunction>
                                <BackEase EasingMode="EaseInOut" />
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                        <DoubleAnimation Storyboard.TargetName="knobPosition" Storyboard.TargetProperty="Y" To="0" Duration="0:0:0.2">
                            <DoubleAnimation.EasingFunction>
                                <BackEase EasingMode="EaseInOut" />
                            </DoubleAnimation.EasingFunction>
                        </DoubleAnimation>
                    </Storyboard>
                </Canvas.Resources>
            </Canvas>
        </Canvas>
    </Grid>
</Window>  

C#:

using System;
using System.Windows;
using System.Windows.Input;

namespace MyApp
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void centerKnob_Completed(object sender, EventArgs e)
        {
        }

        private Point point = new Point();
        private void Knob_MouseDown(object sender, MouseButtonEventArgs e)
        {
            if (e.ChangedButton == MouseButton.Left)
            {
                point = e.GetPosition(this);
            }
        }

        private void Knob_MouseMove(object sender, MouseEventArgs e)
        {
            if (e.LeftButton == MouseButtonState.Pressed)
            {
                double x = e.GetPosition(this).X - point.X;
                double y = e.GetPosition(this).Y - point.Y;

                if (Math.Sqrt(x * x + y * y) < Base.Width / 2)
                {
                    knobPosition.X = x;
                    knobPosition.Y = y;
                }
            }
        }

        private void Knob_MouseUp(object sender, MouseButtonEventArgs e)
        {
            knobPosition.X = 0;
            knobPosition.Y = 0;
        }
    }
}

1 Ответ

0 голосов
/ 22 марта 2020

Я думаю, MouseUp не срабатывает, потому что он выполняется только тогда, когда пользователь отпускает джойстик. Если он выйдет за границы холста до этого, то MouseLeave будет уволен. Таким образом, вы должны сбросить knobPosition и в этом сценарии ..

<!-- [...] -->
<Canvas  x:Name="Knob" VerticalAlignment="Top" HorizontalAlignment="Left" Width="0" Height="0" RenderTransformOrigin="0.5,0.5" Canvas.Left="125" Canvas.Top="125" MouseDown="Knob_MouseDown" MouseMove="Knob_MouseMove" MouseUp="Knob_MouseUp" MouseLeave="Knob_MouseLeave">
<!-- [...] -->

и

private void Knob_MouseLeave(object sender, MouseEventArgs e)
{
    knobPosition.X = 0;
    knobPosition.Y = 0;
}

Надеюсь, я вам помог.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...