在InkCanvas上选择多边形

时间:2012-02-17 07:02:42

标签: c# wpf polygon inkcanvas

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

我编写了这段代码,但它选择了从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);
    }

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

Example

3 个答案:

答案 0 :(得分:2)

我知道这是一个非常古老的帖子,但是我遇到了同样的问题,并通过在转换为多边形之前将点转换为多边形来解决它,然后再回来,如下:

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

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

enter image description here

答案 1 :(得分:0)

好的我解决了我的问题我在我的Window中添加了一个自定义依赖属性,它保存了选定的多边形。为了显示多边形被选中,我改变了它的不透明度。

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

答案 2 :(得分:0)

您可以通过设置

选择画布上的任何绘图
    drawCanvas.EditingMode = InkCanvasEditingMode.Select;

然后只需点击此图。