Нарисуйте линию с высокой толщиной StrokeThickness в silverlight

У меня есть приложение, в котором вы можете рисовать на холсте (например, Paint). Код C# выглядит примерно так:

private void startDrawing(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    _drawingStart = e.GetPosition((UIElement)sender);
    _isDrawing = true;
}

private void stopDrawing(object sender, System.Windows.Input.MouseButtonEventArgs e)
{
    _isDrawing = false;
}

private void doDrawing(object sender, System.Windows.Input.MouseEventArgs e)
{
    if (_isDrawing)
    {
        Point current = e.GetPosition((UIElement)sender);
        Line line = new Line() { X1 = _drawingStart.X, Y1 = _drawingStart.Y, X2 = current.X, Y2 = current.Y };
        line.Stroke = Color;
        line.StrokeThickness = StrokeThickness;
        DrawingCanvas.Children.Add(line);
        _drawingStart = current;
    }
}

И холст:

<Canvas x:Name="DrawingCanvas"
        Grid.Row="1"
        Grid.Column="1"
        Background="Transparent"
        MouseLeftButtonDown="startDrawing"
        MouseLeftButtonUp="stopDrawing"
        MouseMove="doDrawing" />

Когда StrokeThickness мал, все работает нормально. Но если я установлю StrokeThickness на большее число (например, 100), линия будет нарисована в стиле «зигзаг» и не будет «сплошной». Есть идеи, как этого избежать? Или, может быть, как добиться е закругленной линии (закругленные концы линии)? Думаю, это решит проблему.


person drumm3r    schedule 28.04.2015    source источник
comment
Было бы намного проще добавлять точки в набор Points полилинии. Смотрите мой отредактированный ответ.   -  person Clemens    schedule 28.04.2015


Ответы (2)


Я думаю, вы будете очарованы моим ответом:

введите здесь описание изображения

    Point _drawingStart;
    bool _isDrawing;
    private void startDrawing(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        _drawingStart = e.GetPosition((UIElement)sender);
        InitializePath();
        _isDrawing = true;
    }

    private void stopDrawing(object sender, System.Windows.Input.MouseButtonEventArgs e)
    {
        _isDrawing = false;
    }

    private void doDrawing(object sender, System.Windows.Input.MouseEventArgs e)
    {
        if (_isDrawing)
        {
            AddPoint(e.GetPosition((UIElement)sender));
        }
    }
 private void AddPoint(Point newpoint)
 {
        LineSegment l = new LineSegment() { Point = newpoint };
        pathFigure.Segments.Add(l);
        pathFigure.StartPoint = (pathFigure.Segments.First() as LineSegment).Point;
    }

    PathFigure pathFigure;
    Path path;
    private void InitializePath()
    {
        path = new Path()
        {
            StrokeLineJoin = PenLineJoin.Bevel,
            StrokeDashCap = PenLineCap.Round,
            StrokeEndLineCap = PenLineCap.Round,
            StrokeStartLineCap = PenLineCap.Round,
            StrokeThickness = 100.0,
            Stroke = new SolidColorBrush(Colors.Red)
        };

        pathFigure = new PathFigure();
        PathGeometry pathGeometry = new PathGeometry();
        pathGeometry.Figures = new PathFigureCollection();
        pathGeometry.Figures.Add(pathFigure);
        path.Data = pathGeometry;
        DrawingCanvas.Children.Add(path);
    }

Более гладкий, потому что создает реальный путь вместо множества линий, надеюсь, вы найдете его полезным

person Juan Pablo Garcia Coello    schedule 28.04.2015

Вы должны установить для свойства StrokeLineJoin строки значение Bevel или Round.

var line = new Line
{
    X1 = _drawingStart.X,
    Y1 = _drawingStart.Y,
    X2 = current.X,
    Y2 = current.Y,
    Stroke = Color,
    StrokeThickness = StrokeThickness,
    StrokeLineJoin = PenLineJoin.Round
};

См. перечисление PenLineJoin на странице MSDN для получения подробной информации.

В качестве альтернативы вы можете установить StrokeMiterLimit на подходящее значение.


Тем не менее, более элегантным решением было бы добавить точки в коллекцию Points полилинии:

private Polyline currentPolyline;

private void startDrawing(object sender, MouseButtonEventArgs e)
{
    var canvas = (Canvas)sender;

    currentPolyline = new Polyline
    {
        Stroke = Color,
        StrokeThickness = StrokeThickness,
        StrokeStartLineCap = PenLineCap.Round,
        StrokeEndLineCap = PenLineCap.Round,
        StrokeLineJoin = PenLineJoin.Round
    };

    currentPolyline.Points.Add(e.GetPosition(canvas));
    canvas.Children.Add(currentPolyline);
}

private void stopDrawing(object sender, MouseButtonEventArgs e)
{
    currentPolyline = null;
}

private void doDrawing(object sender, MouseEventArgs e)
{
    if (currentPolyline != null)
    {
        currentPolyline.Points.Add(e.GetPosition((UIElement)sender));
    }
}
person Clemens    schedule 28.04.2015