2012-02-17 6 views
0

J'ai une application dans laquelle je dessine des polygones sur inkCanvas. Je voudrais ajouter une fonction où après avoir cliqué sur l'un des polygones dessinés, il serait en mode d'édition et ensuite je pourrais changer certaines de ces proportions, par exemple Fill.Sélection d'un polygone sur InkCanvas

J'ai écrit ce code mais il sélectionne toute la zone en haut à gauche de inkcanvas à la fin de mon polygone mais je n'ai besoin que d'une 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: Je modifié mon code mon premier échantillon était un peu trop général. La sélection d'un polygone ressemble à ceci, mais je veux sélectionner uniquement la zone de polygone.

Example

Répondre

0

Ok je résolu mon problème j'ai ajouté une mesure de propriété de dépendance à ma fenêtre qui contient polygone sélectionné. Pour montrer que le polygone est sélectionné, je change son opacité.

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

Vous pouvez sélectionner le dessin sur votre toile en mettant

drawCanvas.EditingMode = InkCanvasEditingMode.Select; 

et puis juste en cliquant sur ce dessin.

1

Je sais que c'est un poste vraiment vieux, mais j'eu ce même problème et résolu en traduisant les points avant la conversion à un polygone, puis à nouveau, en tant que tel:

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

Cette rend la zone de sélection uniquement égale à la taille du polygone:

enter image description here