C# 在InkCanvas上选择多边形

C# 在InkCanvas上选择多边形,c#,wpf,polygon,inkcanvas,C#,Wpf,Polygon,Inkcanvas,我有一个在inkCanvas上绘制多边形的应用程序。我想添加一个函数,单击其中一个绘制的多边形后,它将处于编辑模式,然后我可以更改一些比例,例如填充 我写了这段代码,但它选择了从inkcanvas左上角到多边形末端的所有区域,但我只需要多边形区域 Xaml: 代码隐藏 private Polyline polyline; private PointCollection polylinePoints; private bool drawOnMove = false;

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

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

Xaml:


代码隐藏

   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);
    }
专用多段线多段线;
私有点集合多段线点;
private bool drawnmove=false;
私有列表多边形=新列表();
公共主窗口()
{
初始化组件();
}
私有void canvas1_MouseMove(对象发送方,MouseEventArgs e)
{
如果(drawOnMove&(bool)rbDraw.IsChecked)
{
polyline.Points=polylinePoints.Clone();
polyline.Points.Add(例如GetPosition(canvas1));
}
}
私有void canvas1_预览鼠标左键向下(对象发送器,鼠标按钮ventargs e)
{
if(rbDraw.IsChecked??false)
{
如果(例如,原始源为椭圆)
{
画布1.儿童。移除((椭圆)e.原始来源);
画布1.儿童。删除(多段线);
多边形tmpPolygon=新多边形();
tmpPolygon.StrokeThickness=2;
tmpPolygon.Stroke=画笔。黑色;
tmpPolygon.Points=polylinePoints.Clone();
polylinePoints.Clear();
多边形。添加(tmpPolygon);
drawOnMove=false;
rbDraw.IsChecked=false;
tmpPolygon.Fill=画笔.灰色;
canvas1.Children.Add(tmpPolygon);
rbSelect.IsChecked=true;
}
其他的
{
添加(例如GetPosition(canvas1));
polyline.Points=polylinePoints.Clone();
如果(polyline.Points.Count==1)
{
椭圆el=新椭圆();
el.宽度=10;
标高高度=10;
el.笔划=画笔。黑色;
el.StrokeThickness=2;
el.Fill=新SolidColorBrush{Color=Colors.Yellow};
el.保证金=
新厚度(左:多段线。点[0]。X-el.Width/2,顶部:多段线。点[0]。Y-el.Height/2,右:0,底部:0);
画布1.儿童。添加(el);
}
drawOnMove=true;
}
}
否则如果(rbSelect.IsChecked??false)
{
如果(例如,原始源为多边形)
{
多边形pol=(多边形)e.原始源;
canvas1.选择(新UIElement[]{pol});
}
}
}
已选中私有无效rbDraw_(对象发送方,路由目标e)
{
多段线=新的多段线();
polylinePoints=新点集合();
折线.StrokeThickness=2;
多段线。笔划=画笔。黑色;
canvas1.Children.Add(多段线);
}
编辑:我编辑了我的代码。我的第一个示例有点太笼统了。选择多边形看起来像这样,但我只想选择多边形区域


好的,我解决了我的问题,我在保存选定多边形的窗口中添加了一个自定义依赖属性。若要显示多边形已选定,请更改其不透明度

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

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

    drawCanvas.EditingMode = InkCanvasEditingMode.Select;

然后点击这张图。

我知道这是一篇非常古老的文章,但我遇到了完全相同的问题,通过将转换前的点转换为多边形,然后再转换回来,解决了这个问题,如下所示:

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_);
这使得选择框仅等于多边形的大小:

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