Question

J'ai une application où je dessine des polygones sur InkCanvas. Je voudrais ajouter une fonction où après avoir cliqué sur un des polygones dessinés, il serait en mode édition, puis je pouvais changer une partie de ce proporties par exemple remplissage.

J'ai écrit ce code, mais il sélectionne tout en haut à gauche de la zone de InkCanvas à la fin de mon polygone mais j'ai besoin que zone de polygone.

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 derrière

   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: J'édité mon code mon premier échantillon était un peu trop général. La sélection de regards de polygones comme cela, mais je veux sélectionner uniquement la zone polygone.

Exemple

Était-ce utile?

La solution 2

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

Autres conseils

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

You can select any drawing on your canvas by setting

    drawCanvas.EditingMode = InkCanvasEditingMode.Select;

and then just clicking on this drawing.

Licencié sous: CC-BY-SA avec attribution
Non affilié à StackOverflow
scroll top