在 InkCanvas 上选择多边形

发布于 2025-01-06 15:43:54 字数 4515 浏览 4 评论 0原文

我有一个在 inkCanvas 上绘制多边形的应用程序。我想添加一个功能,在单击绘制的多边形之一后,它将处于编辑模式,然后我可以更改其中一些比例,例如填充。

我编写了这段代码,但它选择了从 inkcanvas 左上角到多边形末尾的所有区域,但我只需要多边形区域。

Xaml:

<DockPanel>
    <ToolBarTray DockPanel.Dock="Left" Orientation="Vertical" IsLocked="True">
        <ToolBar Padding="2">
            <RadioButton x:Name="rbDraw" IsChecked="False"
                    ToolTip="Add Rectangle" Margin="3" Checked="rbDraw_Checked">
                <Rectangle Width="20" Height="12" Stroke="Blue"
                    Fill="LightBlue" />
            </RadioButton>
            <RadioButton x:Name="rbSelect" IsChecked="False"
                ToolTip="Select" Margin="3">
                <Path Stroke="Blue" Fill="LightBlue" Width="20" Height="20">
                    <Path.Data>
                        <PathGeometry Figures="M5,15L 10,0 15,15 12,15 12,20 8,20 8,15Z">
                            <PathGeometry.Transform>
                                <RotateTransform CenterX="10" CenterY="10" Angle="45"/>
                            </PathGeometry.Transform>
                        </PathGeometry>
                    </Path.Data>
                </Path>
            </RadioButton>
        </ToolBar>
    </ToolBarTray>
    <Border BorderThickness="1" BorderBrush="Black">
        <InkCanvas x:Name="canvas1" MouseMove="canvas1_MouseMove" PreviewMouseLeftButtonDown="canvas1_PreviewMouseLeftButtonDown" EditingMode="None">
        </InkCanvas>
    </Border>
</DockPanel>

代码隐藏

   private Polyline polyline;
    private PointCollection polylinePoints;
    private bool drawOnMove = false;
    private List<Polygon> polygons = new List<Polygon>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void canvas1_MouseMove(object sender, MouseEventArgs e)
    {
        if (drawOnMove && (bool)rbDraw.IsChecked)
        {
            polyline.Points = polylinePoints.Clone();
            polyline.Points.Add(e.GetPosition(canvas1));
        }
    }

    private void canvas1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (rbDraw.IsChecked ?? false)
        {
            if (e.OriginalSource is Ellipse)
            {
                canvas1.Children.Remove((Ellipse)e.OriginalSource);
                canvas1.Children.Remove(polyline);
                Polygon tmpPolygon = new Polygon();
                tmpPolygon.StrokeThickness = 2;
                tmpPolygon.Stroke = Brushes.Black;
                tmpPolygon.Points = polylinePoints.Clone();
                polylinePoints.Clear();

                polygons.Add(tmpPolygon);
                drawOnMove = false;
                rbDraw.IsChecked = false;
                tmpPolygon.Fill = Brushes.Gray;
                canvas1.Children.Add(tmpPolygon);
                rbSelect.IsChecked = true;

            }
            else
            {
                polylinePoints.Add(e.GetPosition(canvas1));
                polyline.Points = polylinePoints.Clone();

                if (polyline.Points.Count == 1)
                {
                    Ellipse el = new Ellipse();
                    el.Width = 10;
                    el.Height = 10;
                    el.Stroke = Brushes.Black;
                    el.StrokeThickness = 2;
                    el.Fill = new SolidColorBrush { Color = Colors.Yellow };
                    el.Margin =
                        new Thickness(left: polyline.Points[0].X - el.Width / 2, top: polyline.Points[0].Y - el.Height / 2, right: 0, bottom: 0);
                    canvas1.Children.Add(el);
                }

                drawOnMove = true;
            }
        }
        else if (rbSelect.IsChecked ?? false) 
        {
            if (e.OriginalSource is Polygon)
            {
                Polygon pol = (Polygon)e.OriginalSource;

                canvas1.Select(new UIElement[] { pol });
            }
        }
    }

    private void rbDraw_Checked(object sender, RoutedEventArgs e)
    {
        polyline = new Polyline();
        polylinePoints = new PointCollection();
        polyline.StrokeThickness = 2;
        polyline.Stroke = Brushes.Black;
        canvas1.Children.Add(polyline);
    }

编辑:我编辑了我的代码,我的第一个示例有点太笼统了。选择多边形看起来像这样,但我只想选择多边形区域。

示例

I have an application where I draw polygons on inkCanvas. I would like to add a function where after clicking one of drawn polygons it would be in editing mode and then I could change some of this proporties for example Fill.

I wrote this code but it selects all area from top left of inkcanvas to the end of my polygon but I need only polygon area.

Xaml:

<DockPanel>
    <ToolBarTray DockPanel.Dock="Left" Orientation="Vertical" IsLocked="True">
        <ToolBar Padding="2">
            <RadioButton x:Name="rbDraw" IsChecked="False"
                    ToolTip="Add Rectangle" Margin="3" Checked="rbDraw_Checked">
                <Rectangle Width="20" Height="12" Stroke="Blue"
                    Fill="LightBlue" />
            </RadioButton>
            <RadioButton x:Name="rbSelect" IsChecked="False"
                ToolTip="Select" Margin="3">
                <Path Stroke="Blue" Fill="LightBlue" Width="20" Height="20">
                    <Path.Data>
                        <PathGeometry Figures="M5,15L 10,0 15,15 12,15 12,20 8,20 8,15Z">
                            <PathGeometry.Transform>
                                <RotateTransform CenterX="10" CenterY="10" Angle="45"/>
                            </PathGeometry.Transform>
                        </PathGeometry>
                    </Path.Data>
                </Path>
            </RadioButton>
        </ToolBar>
    </ToolBarTray>
    <Border BorderThickness="1" BorderBrush="Black">
        <InkCanvas x:Name="canvas1" MouseMove="canvas1_MouseMove" PreviewMouseLeftButtonDown="canvas1_PreviewMouseLeftButtonDown" EditingMode="None">
        </InkCanvas>
    </Border>
</DockPanel>

Code behind

   private Polyline polyline;
    private PointCollection polylinePoints;
    private bool drawOnMove = false;
    private List<Polygon> polygons = new List<Polygon>();

    public MainWindow()
    {
        InitializeComponent();
    }

    private void canvas1_MouseMove(object sender, MouseEventArgs e)
    {
        if (drawOnMove && (bool)rbDraw.IsChecked)
        {
            polyline.Points = polylinePoints.Clone();
            polyline.Points.Add(e.GetPosition(canvas1));
        }
    }

    private void canvas1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (rbDraw.IsChecked ?? false)
        {
            if (e.OriginalSource is Ellipse)
            {
                canvas1.Children.Remove((Ellipse)e.OriginalSource);
                canvas1.Children.Remove(polyline);
                Polygon tmpPolygon = new Polygon();
                tmpPolygon.StrokeThickness = 2;
                tmpPolygon.Stroke = Brushes.Black;
                tmpPolygon.Points = polylinePoints.Clone();
                polylinePoints.Clear();

                polygons.Add(tmpPolygon);
                drawOnMove = false;
                rbDraw.IsChecked = false;
                tmpPolygon.Fill = Brushes.Gray;
                canvas1.Children.Add(tmpPolygon);
                rbSelect.IsChecked = true;

            }
            else
            {
                polylinePoints.Add(e.GetPosition(canvas1));
                polyline.Points = polylinePoints.Clone();

                if (polyline.Points.Count == 1)
                {
                    Ellipse el = new Ellipse();
                    el.Width = 10;
                    el.Height = 10;
                    el.Stroke = Brushes.Black;
                    el.StrokeThickness = 2;
                    el.Fill = new SolidColorBrush { Color = Colors.Yellow };
                    el.Margin =
                        new Thickness(left: polyline.Points[0].X - el.Width / 2, top: polyline.Points[0].Y - el.Height / 2, right: 0, bottom: 0);
                    canvas1.Children.Add(el);
                }

                drawOnMove = true;
            }
        }
        else if (rbSelect.IsChecked ?? false) 
        {
            if (e.OriginalSource is Polygon)
            {
                Polygon pol = (Polygon)e.OriginalSource;

                canvas1.Select(new UIElement[] { pol });
            }
        }
    }

    private void rbDraw_Checked(object sender, RoutedEventArgs e)
    {
        polyline = new Polyline();
        polylinePoints = new PointCollection();
        polyline.StrokeThickness = 2;
        polyline.Stroke = Brushes.Black;
        canvas1.Children.Add(polyline);
    }

Edit: I edited my code my first sample was a little too general. Selecting polygon looks like this but I want to select only polygon area.

Example

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

腹黑女流氓 2025-01-13 15:43:54

我知道这是一篇非常旧的帖子,但我遇到了完全相同的问题,并通过将转换之前的点转换为多边形然后再返回来解决它,如下所示:

StrokeCollection sc = InkCanvas1.GetSelectedStrokes();
Rect r = sc.GetBounds();

PointCollection pc = new PointCollection();

//Shift all the points by the calculated extent of the strokes.
Matrix mat = new Matrix();
mat.Translate(-r.Left, -r.Top);

sc.Transform(mat, false);
foreach (Stroke s in sc)
{
    foreach (Point p in s.StylusPoints){pc.Add(p);}
}
Polygon poly_ = new Polygon();

//Shift the polygon back to original location
poly_.SetValue(InkCanvas.LeftProperty, r.Left);
poly_.SetValue(InkCanvas.TopProperty, r.Top);

poly_.Points = pc;
InkCanvas1.Children.Add(poly_);

这使得选择框仅等于多边形:

在此处输入图像描述

I know this is a really old post, but I had this exact same problem and solved it by translating the points before the conversion to a polygon, and then back again, as such:

StrokeCollection sc = InkCanvas1.GetSelectedStrokes();
Rect r = sc.GetBounds();

PointCollection pc = new PointCollection();

//Shift all the points by the calculated extent of the strokes.
Matrix mat = new Matrix();
mat.Translate(-r.Left, -r.Top);

sc.Transform(mat, false);
foreach (Stroke s in sc)
{
    foreach (Point p in s.StylusPoints){pc.Add(p);}
}
Polygon poly_ = new Polygon();

//Shift the polygon back to original location
poly_.SetValue(InkCanvas.LeftProperty, r.Left);
poly_.SetValue(InkCanvas.TopProperty, r.Top);

poly_.Points = pc;
InkCanvas1.Children.Add(poly_);

This makes the select box only equal to the size of the polygon:

enter image description here

甩你一脸翔 2025-01-13 15:43:54

好的,我解决了我的问题,我向我的窗口添加了一个自定义依赖属性,其中包含选定的多边形。为了显示多边形已被选中,我更改了其不透明度。

 public static readonly DependencyProperty SelectedShapeProperty =
       DependencyProperty.Register
       ("SelectedShape", typeof(Polygon), typeof(MainWindow));

    public Polygon Polygon 
    {
        set{SetValue(SelectedShapeProperty, value);}
        get{return (Polygon) GetValue(SelectedShapeProperty);}
    }


 private void canvas1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (rbDraw.IsChecked ?? false)
        {
            if (e.OriginalSource is Ellipse)
            {
                canvas1.Children.Remove((Ellipse)e.OriginalSource);
                canvas1.Children.Remove(polyline);
                Polygon tmpPolygon = new Polygon();
                tmpPolygon.StrokeThickness = 2;
                tmpPolygon.Stroke = Brushes.Black;
                tmpPolygon.Points = polylinePoints.Clone();
                polylinePoints.Clear();

                polygons.Add(tmpPolygon);
                drawOnMove = false;
                rbDraw.IsChecked = false;
                tmpPolygon.Fill = Brushes.Gray;
                canvas1.Children.Add(tmpPolygon);
                rbSelect.IsChecked = true;

            }
            else
            {
                polylinePoints.Add(e.GetPosition(canvas1));
                polyline.Points = polylinePoints.Clone();

                if (polyline.Points.Count == 1)
                {
                    Ellipse el = new Ellipse();
                    el.Width = 10;
                    el.Height = 10;
                    el.Stroke = Brushes.Black;
                    el.StrokeThickness = 2;
                    el.Fill = new SolidColorBrush { Color = Colors.Yellow };
                    InkCanvas.SetLeft(el, polyline.Points[0].X - el.Width / 2);
                    InkCanvas.SetTop(el, polyline.Points[0].Y - el.Height / 2);

                    el.Margin =
                        new Thickness(left: polyline.Points[0].X - el.Width / 2, top: polyline.Points[0].Y - el.Height / 2, right: 0, bottom: 0);
                    canvas1.Children.Add(el);
                }

                drawOnMove = true;
            }
        }
        else if (rbSelect.IsChecked ?? false)
        {
            if (e.OriginalSource is Polygon && Polygon == null)
            {
                Shape s = (Shape)e.OriginalSource;
                Polygon = (Polygon)s;
                Polygon.Opacity = 0.75;
            }
            else if (e.OriginalSource is Polygon && Polygon != null)
            {
                Polygon.Opacity = 1;
                Polygon = null;
                Shape s = (Shape)e.OriginalSource;
                Polygon = (Polygon)s;
                Polygon.Opacity = 0.75;
            }
            else if (Polygon != null)
            {
                Polygon.Opacity = 1;
                Polygon = null;
            }
        }
        else
        {
            if(Polygon != null)
                Polygon = null;
        }
    }

Ok I solved my problem I added a custom Dependency Property to my Window which holds selected polygon. To show that polygon is selected I change its opacity.

 public static readonly DependencyProperty SelectedShapeProperty =
       DependencyProperty.Register
       ("SelectedShape", typeof(Polygon), typeof(MainWindow));

    public Polygon Polygon 
    {
        set{SetValue(SelectedShapeProperty, value);}
        get{return (Polygon) GetValue(SelectedShapeProperty);}
    }


 private void canvas1_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (rbDraw.IsChecked ?? false)
        {
            if (e.OriginalSource is Ellipse)
            {
                canvas1.Children.Remove((Ellipse)e.OriginalSource);
                canvas1.Children.Remove(polyline);
                Polygon tmpPolygon = new Polygon();
                tmpPolygon.StrokeThickness = 2;
                tmpPolygon.Stroke = Brushes.Black;
                tmpPolygon.Points = polylinePoints.Clone();
                polylinePoints.Clear();

                polygons.Add(tmpPolygon);
                drawOnMove = false;
                rbDraw.IsChecked = false;
                tmpPolygon.Fill = Brushes.Gray;
                canvas1.Children.Add(tmpPolygon);
                rbSelect.IsChecked = true;

            }
            else
            {
                polylinePoints.Add(e.GetPosition(canvas1));
                polyline.Points = polylinePoints.Clone();

                if (polyline.Points.Count == 1)
                {
                    Ellipse el = new Ellipse();
                    el.Width = 10;
                    el.Height = 10;
                    el.Stroke = Brushes.Black;
                    el.StrokeThickness = 2;
                    el.Fill = new SolidColorBrush { Color = Colors.Yellow };
                    InkCanvas.SetLeft(el, polyline.Points[0].X - el.Width / 2);
                    InkCanvas.SetTop(el, polyline.Points[0].Y - el.Height / 2);

                    el.Margin =
                        new Thickness(left: polyline.Points[0].X - el.Width / 2, top: polyline.Points[0].Y - el.Height / 2, right: 0, bottom: 0);
                    canvas1.Children.Add(el);
                }

                drawOnMove = true;
            }
        }
        else if (rbSelect.IsChecked ?? false)
        {
            if (e.OriginalSource is Polygon && Polygon == null)
            {
                Shape s = (Shape)e.OriginalSource;
                Polygon = (Polygon)s;
                Polygon.Opacity = 0.75;
            }
            else if (e.OriginalSource is Polygon && Polygon != null)
            {
                Polygon.Opacity = 1;
                Polygon = null;
                Shape s = (Shape)e.OriginalSource;
                Polygon = (Polygon)s;
                Polygon.Opacity = 0.75;
            }
            else if (Polygon != null)
            {
                Polygon.Opacity = 1;
                Polygon = null;
            }
        }
        else
        {
            if(Polygon != null)
                Polygon = null;
        }
    }
燃情 2025-01-13 15:43:54

您可以通过设置选择画布上的任何绘图

    drawCanvas.EditingMode = InkCanvasEditingMode.Select;

,然后只需单击该绘图即可。

You can select any drawing on your canvas by setting

    drawCanvas.EditingMode = InkCanvasEditingMode.Select;

and then just clicking on this drawing.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文