Выбор многоугольника на чернил
Вопрос
У меня есть приложение, в котором я рисую многоугольники на inkcanvas. Я хотел бы добавить функцию, в которой после нажатия одного из нарисованных многоугольников она будет в режиме редактирования, а затем я мог бы изменить некоторые из этих пропорций, например, заполнить.
Я написал этот код, но он выбирает всю область сверху слева от 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);
}
РЕДАКТИРОВАТЬ: Я отредактировал свой код, мой первый образец был слишком общим. Выбор многоугольника выглядит так, но я хочу выбрать только многоугольную область.
Решение 2
ОК, я решил свою проблему, я добавил в свое окно собственное свойство зависимости, которое содержит выбранную многоугольника. Чтобы показать, что полигон выбран, я меняю его непрозрачность.
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;
}
}
Другие советы
Я знаю, что это действительно старый пост, но у меня была такая же проблема, и он решил ее, переведя очки перед переходом в многоугольник, а затем снова, как таковой:
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_);
Это делает поле выбора только равным размеру многоугольника:
Вы можете выбрать любой рисунок на своем холсте, настройка
drawCanvas.EditingMode = InkCanvasEditingMode.Select;
А потом просто нажав на этот рисунок.