3

我不知道我的代码或 WPF 是否有问题,但问题是:我想创建一个小程序,您可以在其中使用光标在画布上进行绘制。我有一个简单的 WPF 窗口:

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="MainWindow" Height="475" Width="544">
<Grid>    
    <Grid.RowDefinitions>
        <RowDefinition Height="100px"></RowDefinition>
        <RowDefinition Height ="*"></RowDefinition>
        <RowDefinition Height="100px"></RowDefinition>
    </Grid.RowDefinitions>    
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="100px"></ColumnDefinition>
        <ColumnDefinition Width="*"></ColumnDefinition>
        <ColumnDefinition Width="100px"></ColumnDefinition>
    </Grid.ColumnDefinitions>
        <Canvas Grid.Row="1" Grid.Column="1"  Name="imageCanvas" MouseEnter="StackPanel_MouseEnter" MouseLeave="StackPanel_MouseLeave" Background="LightGray" 
                      MouseDown="StackPan_MouseDown" MouseUp="StackPan_MouseUp" MouseMove="StackPan_MouseMove">

        </Canvas>        
</Grid>

下面是后台代码:

   private void StackPan_MouseDown(object sender, MouseButtonEventArgs e)
    {
        draw = true;
    }

    private void StackPan_MouseUp(object sender, MouseButtonEventArgs e)
    {
        draw = false;
    }

    private void StackPan_MouseMove(object sender, MouseEventArgs e)
    {
        if (draw)
        {
            var pos = Mouse.GetPosition(imageCanvas);
            Rectangle rec = new Rectangle()
                    {
                        Width = 10,
                        Height = 10,
                        Fill = Brushes.Red,
                    };
            Canvas.SetTop(rec, pos.Y);
            Canvas.SetLeft(rec, pos.X);
            imageCanvas.Children.Add(rec);
        }

    }

我能做的是以下几点: https ://www.dropbox.com/s/7moq4p8f8f409b3/wpf_canvas.png

为什么当光标在画布之外时调用 StackPan_MouseMove?

这是可执行文件,您可以在其中注意到这种行为: https ://www.dropbox.com/s/ye1w2j9chld2oif/WpfApplication1.exe

4

2 回答 2

1

您可以通过 Canvas 的 Rectangle 子项获得 MouseMove 事件。

尽管您最好使用 InkPresenter 或 InkCanvas(正如用户 keyboardP 所说),但您可以简单地使 Rectangles 对命中测试不可见。然后它们将不再产生任何输入事件。

Rectangle rec = new Rectangle()
{
    Width = 10,
    Height = 10,
    Fill = Brushes.Red,
    IsHitTestVisible = false // here
};
于 2013-09-20T13:59:10.100 回答
1

尝试将 Canvas 放置在 Border 控件中并将Border控件的ClipToBounds属性设置为true

<Border ClipToBounds="true" Grid.Row="1" Grid.Column="1" >
    <Canvas Name="imageCanvas" MouseEnter="StackPanel_MouseEnter" MouseLeave="StackPanel_MouseLeave" Background="LightGray" 
            MouseDown="StackPan_MouseDown" MouseUp="StackPan_MouseUp" MouseMove="StackPan_MouseMove">
    </Canvas>
</Border>

稍有不同的是,似乎InkPresenter / InkCanvas可能更适合您尝试执行的操作,除非您出于特定原因避免使用它们。

于 2013-09-20T13:59:23.850 回答