Pregunta

Tengo una aplicación donde dibujo polígonos en Inkcanvas. Me gustaría agregar una función donde después de hacer clic en uno de los polígonos dibujados estaría en modo de edición y luego podría cambiar algunas de estas proporciones, por ejemplo, llenar.

Escribí este código pero selecciona toda el área desde la parte superior izquierda de Inkcanvas hasta el final de mi polígono, pero solo necesito área de polígono.

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>

Código detrás

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

Editar: edité mi código. Mi primera muestra era demasiado general. Seleccionar polígono se ve así, pero quiero seleccionar solo un área de polígono.

Example

¿Fue útil?

Solución 2

Ok, resolví mi problema, agregué una propiedad de dependencia personalizada a mi ventana que contiene el polígono seleccionado. Para mostrar que se selecciona Polygon, cambio su opacidad.

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

Otros consejos

Sé que esta es una publicación realmente antigua, pero tuve este mismo problema y lo resolví traduciendo los puntos antes de la conversión a un polígono, y luego de nuevo, como tal:

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

Esto hace que el cuadro de selección solo sea igual al tamaño del polígono:

enter image description here

Puede seleccionar cualquier dibujo en su lienzo configurando

    drawCanvas.EditingMode = InkCanvasEditingMode.Select;

Y luego simplemente haciendo clic en este dibujo.

Licenciado bajo: CC-BY-SA con atribución
No afiliado a StackOverflow
scroll top