I can't find the answer on Google.
I have many strings to be presented on a canvas. Each string will be created using the FormattedText() method within a string converter called from an ItemsControl.
The problem with the code is that it needs a ridiculously large width and height in the RenderTargetBitmap() to display all the strings at different positions, even though each string has an approximate actual width of 700 and actual height of 40. (It seems as though the RenderTargetBitmap() needs to be large enough to hold not just the string, but also the position of that string from the drawing context).
How do you create an image of just a single formatted text string with the correct actual height and width of just the Formatted Text and then correctly position that image at the point of "topleft" ?
The converter called from an ItemsControl is defined as:
public class InkConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
var stringviewmodel = value as StringViewModel;
if (stringviewmodel != null)
{
stringviewmodel.ft = new FormattedText(
stringviewmodel.text,
CultureInfo.CurrentCulture,
FlowDirection.LeftToRight,
new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal),
stringviewmodel.emSize,
stringviewmodel.color);
stringviewmodel.ft.TextAlignment = TextAlignment.Left;
stringviewmodel.ft.LineHeight =(double)stringviewmodel.lineheight;
Image myImage = new Image();
DrawingVisual dw = new DrawingVisual();
DrawingContext dc = dw.RenderOpen();
dc.DrawText(stringviewmodel.ft, stringviewmodel.topleft);
dc.Close();
int Width = 2000;
int Height = 2000;
RenderTargetBitmap bmp = new RenderTargetBitmap(Width, Height, 120, 96, PixelFormats.Pbgra32);
bmp.Render(dw);
myImage.Source = bmp;
return myImage;
}
else
{
return null;
}
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
Addendum:
I wrote this which solved the problem, but does not answer my question. (gt and lt symbols removed).
Changed the itemscontrol to include:
ItemsControl.ItemContainerStyle Style TargetType="{x:Type FrameworkElement} Setter Property="Canvas.Top" Value="{Binding topleft.Y}" Setter Property="Canvas.Left" Value="{Binding topleft.X}" Setter Property="Height" Value="{Binding ft.Height}"
Removed all positioning from the Converter. The converter now reads as
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { var stringviewmodel = value as StringViewModel; if (stringviewmodel != null) { stringviewmodel.ft = new FormattedText( stringviewmodel.text, CultureInfo.CurrentCulture, FlowDirection.LeftToRight, new Typeface(new FontFamily("Segoe Script"), FontStyles.Italic, FontWeights.Normal, FontStretches.Normal), stringviewmodel.emSize, stringviewmodel.color); stringviewmodel.ft.TextAlignment = TextAlignment.Left; stringviewmodel.ft.LineHeight =(double)stringviewmodel.lineheight; Image myImage = new Image(); DrawingVisual dw = new DrawingVisual(); DrawingContext dc = dw.RenderOpen(); dc.DrawText(stringviewmodel.ft, new Point(0,0)); dc.Close(); double width = stringviewmodel.ft.text.Width - stringviewmodel.text.OverhangLeading - stringviewmodel.text.OverhangTrailing; RenderTargetBitmap bmp = new RenderTargetBitmap( (int)(width, (int)stringviewmodel.ft.Height, 96d, 96d, PixelFormats.Pbgra32); bmp.Render(dw); myImage.Source = bmp; return myImage; } else { return null; } }