#c# #wpf #textbox #stroke #inkcanvas
#c# #wpf #текстовое поле #обводка #inkcanvas
Вопрос:
Я использую InkCanvas, на котором я отображаю некоторые пользовательские обводки (в основном для представления некоторых фигур, таких как прямоугольник или округленный прямоугольник). Я прекрасно могу рисовать, выбирать, перемещать и изменять размер этих фигур, но теперь я хочу добавить немного текста внутри этих фигур.
Дело в том, что пользовательские штрихи не могут содержать список дочерних элементов, поэтому я не могу добавить текстовое поле к определенному штриху. Я попытался добавить текстовое поле в определенную позицию (относительно положения штриха) внутри дочерних элементов InkCanvas, но результат довольно плохой, потому что текстовое поле всегда находится за моим пользовательским штрихом.
Есть ли какой-либо способ сделать это?
Спасибо
Редактировать: Это код xaml
<InkCanvas ClipToBounds="True" Grid.Column="0" Grid.Row="0" Name="surfaceDessin"
HorizontalAlignment="Stretch" VerticalAlignment="Stretch"
MouseLeave="surfaceDessin_MouseLeave" MouseMove="surfaceDessin_MouseMove" PreviewMouseMove="InkCanvas_LeftMouseMove" PreviewMouseUp="InkCanvas_LeftMouseUp" PreviewMouseDown="InkCanvas_LeftMouseDown"
Strokes="{Binding Path=Traits, Mode=OneTime}" EditingMode="{Binding Path=OutilSelectionne, Converter={StaticResource convertisseurModeEdition}, UpdateSourceTrigger=PropertyChanged, Mode=OneWay}"
DefaultDrawingAttributes="{Binding Path=AttributsDessin, Mode=OneTime}"/>
Комментарии:
1. Можете ли вы показать свой текущий код XAML для этого?
2. Я добавил XAML-код InkCanvas. Большая часть того, что мы делаем (например, добавление пользовательской формы в surfaceDessin. Штрихи) выполняются на C #.
3. просто опубликовал кое-что в качестве ответа, потому что было долго публиковать здесь в качестве комментария
Ответ №1:
Поскольку я не знаю точно, что происходит на стороне C #, я провел небольшой эксперимент, похоже, вы можете использовать свой контекст рисования в своем пользовательском классе stroke (я понимаю, что у вас есть один), чтобы нарисовать текст в нужном вам месте. Даже если это не идеальное решение, я все равно думаю, что это лучше, чем взламывать его с помощью текстового поля. В итоге вам нужно добавить только одну строку в ваш пользовательский класс обводки (drawingcontext.DrawText ….)
PS: код в основном взят из других источников, а не полностью мой собственный.
using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Ink;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
public void DrawTextInRectangle(object sender, RoutedEventArgs e)
{
StylusPointCollection pts = new StylusPointCollection();
pts.Add(new StylusPoint(100, 100));
pts.Add(new StylusPoint(100, 300));
pts.Add(new StylusPoint(300, 300));
pts.Add(new StylusPoint(300, 100));
pts.Add(new StylusPoint(100, 100));
CustomStroke st = new CustomStroke(pts);
st.DrawingAttributes.Color = Colors.Red;
inkCanvas1.Strokes.Add(st);
}
}
}
// A class for rendering custom strokes
class CustomStroke : Stroke
{
Brush brush;
Pen pen;
public CustomStroke(StylusPointCollection stylusPoints)
: base(stylusPoints)
{
// Create the Brush and Pen used for drawing.
brush = new LinearGradientBrush(Colors.Red, Colors.Blue, 20d);
pen = new Pen(brush, 2d);
}
protected override void DrawCore(DrawingContext drawingContext,
DrawingAttributes drawingAttributes)
{
// Allocate memory to store the previous point to draw from.
Point prevPoint = new Point(double.NegativeInfinity,
double.NegativeInfinity);
// Draw linear gradient ellipses between
// all the StylusPoints in the Stroke.
for (int i = 0; i < this.StylusPoints.Count; i )
{
Point pt = (Point)this.StylusPoints[i];
Vector v = Point.Subtract(prevPoint, pt);
// Only draw if we are at least 4 units away
// from the end of the last ellipse. Otherwise,
// we're just redrawing and wasting cycles.
if (v.Length > 4)
{
// Set the thickness of the stroke
// based on how hard the user pressed.
double radius = this.StylusPoints[i].PressureFactor * 10d;
drawingContext.DrawEllipse(brush, pen, pt, radius, radius);
prevPoint = pt;
}
}
Typeface tf = new Typeface("Arial");
FormattedText ft = new FormattedText("test test", CultureInfo.CurrentCulture, FlowDirection.LeftToRight, tf, 15, Brushes.Red);
drawingContext.DrawText(ft, new Point(1.5 * prevPoint.X, 1.5 * prevPoint.Y));
}
}