【问题标题】:WPF Application - Not able to change rectangle properties on MouseDownWPF 应用程序 - 无法更改 MouseDown 上的矩形属性
【发布时间】:2019-03-14 07:54:10
【问题描述】:

我有一个简单的 WPF 应用程序,它是一个窗口应用程序。此窗口上有一个画布。我想要做的是当我在画布上移动鼠标时它应该在画布上绘制一个矩形,然后当我按下鼠标左键时,矩形的颜色应该会改变。我完全能够在鼠标移动事件上绘制一个矩形,并在 Rectangle 上接收 MouseDown 事件,但是当我尝试更改此矩形的颜色时它不起作用。代码很简单

这是我的 xaml 文件

<Window x:Class="WpfApp1.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:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Canvas Background="#11FFFFFF"  IsHitTestVisible="True" x:Name="overlay" Opacity="1">

        </Canvas>
    </Grid>
</Window>

这是我的 xaml.cs 文件

namespace WpfApp1
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            overlay.MouseMove += OnOverlayMouseMove;
        }

        private void OnOverlayMouseMove(object sender, MouseEventArgs args)
        {
            overlay.Children.Clear();

            Point ps = args.GetPosition(overlay);

            Rectangle rect = new Rectangle
            {
                Fill = Brushes.LightBlue,
                Stroke = Brushes.LightGray,
                StrokeThickness = 2,
                Width = 100,
                Height = 50
            };

            rect.Opacity = 0.5;
            rect.MouseLeftButtonDown += OnRectLeftMouseButtonDown;
            rect.Name = "Blue";

            Canvas.SetLeft(rect, ps.X - 50);
            Canvas.SetTop(rect, ps.Y - 25);
            overlay.Children.Add(rect);
        }

        private void OnRectLeftMouseButtonDown(object sender, MouseEventArgs args)
        {
            Rectangle rect = sender as Rectangle;

            if (rect.Name.Equals("Blue"))
            {
                rect.Fill = Brushes.Black;
                rect.Name = "Black";
            }
            else
            {
                rect.Fill = Brushes.LightBlue;
                rect.Name = "Blue";
            }

            args.Handled = true;
        }
    }
}

【问题讨论】:

  • 请注意,您不应该在每次鼠标移动时清除画布并创建一个新的矩形。这效率极低。

标签: c# wpf wpf-controls


【解决方案1】:

颜色没有改变,因为每次调用 OnOverlayMouseMove 并将 Fill 设置为 LightBlue 时,您都在创建一个新矩形

您可以执行以下操作,

    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            overlay.MouseMove += OnOverlayMouseMove;
        }

        private void OnOverlayMouseMove(object sender, MouseEventArgs args)
        {
            overlay.Children.Clear();

            Point ps = args.GetPosition(overlay);

            Rectangle rect = new Rectangle
            {
                Fill = brush,
                Stroke = Brushes.LightGray,
                StrokeThickness = 2,
                Width = 100,
                Height = 50
            };

            rect.Opacity = 0.5;
            rect.MouseLeftButtonDown += OnRectLeftMouseButtonDown;
            rect.Name = "Blue";

            Canvas.SetLeft(rect, ps.X - 50);
            Canvas.SetTop(rect, ps.Y - 25);
            overlay.Children.Add(rect);
        }
        private SolidColorBrush brush = Brushes.LightBlue;
        private void OnRectLeftMouseButtonDown(object sender, MouseEventArgs args)
        {
            Rectangle rect = sender as Rectangle;

            if (brush == Brushes.LightBlue)
            {
                brush = Brushes.Black;
            }
            else
            {
                brush = Brushes.LightBlue;
            }

            args.Handled = true;
        }
    }

【讨论】:

  • 不,它不工作...你请在你最后尝试一下
  • 我的目标不仅仅是改变矩形的颜色,还要改变这个矩形的一些属性...
  • 认为您忘记包含不每次都创建新矩形的代码。
  • Rectangle rect = sender as Rectangle; 不会创建新的矩形。请仔细看看这个问题。
  • 我在 OnOverlayMouseMove 中说他正在创建一个新矩形,请仔细阅读答案
【解决方案2】:

我认为你需要这样的东西:

public partial class MainWindow : Window
{
    private Color normal = Color.FromRgb(255, 0, 0);
    private Color active = Color.FromRgb(0, 0, 0);

    private SolidColorBrush rectangleBrush;


    public MainWindow()
    {
        InitializeComponent();

        rectangleBrush = new SolidColorBrush(normal);
        overlay.MouseMove += OnOverlayMouseMove;
    }

    private void OnOverlayMouseMove(object sender, MouseEventArgs args)
    {
        overlay.Children.Clear();

        Point ps = args.GetPosition(overlay);

        Rectangle rect = new Rectangle
        {
            Fill = rectangleBrush,
            Stroke = Brushes.LightGray,
            StrokeThickness = 2,
            Width = 100,
            Height = 50
        };

        rect.Opacity = 0.5;
        rect.MouseLeftButtonDown += OnRectLeftMouseButtonDown;

        Canvas.SetLeft(rect, ps.X - 50);
        Canvas.SetTop(rect, ps.Y - 25);
        overlay.Children.Add(rect);
    }

    private void OnRectLeftMouseButtonDown(object sender, MouseEventArgs args)
    {
        Rectangle rect = sender as Rectangle;

        if ((rect.Fill as SolidColorBrush).Color == normal) {
            rectangleBrush.Color = active;
        } else {
            rectangleBrush.Color = normal;
        }

        args.Handled = true;
    }
}

如果您想使用 Color 结构中的颜色,只需将普通和活动变量替换为“Colors.LightBlue”和“Colors.Black”

【讨论】:

    猜你喜欢
    • 2012-06-22
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2012-02-03
    • 1970-01-01
    • 2010-10-31
    • 2023-03-30
    相关资源
    最近更新 更多