c# - 如何使用 OnRender 自定义 TextBlock

标签 c# wpf xaml textblock

我无法理解...我开始认为它无法完成。

我想创建一个允许测量包含的文本的自定义文本 block 控件。我不能执行以下操作,因为 OnRender() 是密封的。但是,如果我使用 new,则永远不会调用我的新“OnRender()”。那怎么办呢?有没有更好的办法? (CustomTextBlock 在 MVVM 框架的 ItemsControl 中使用。我不想创建任何额外的依赖属性)。

请提前告知并感谢。

XAML 中的用法:

 <i:CustomTextBlock Grid.Row="0"  x:Name="tbc"
               Text="{Binding Text}" 
               FontSize="{Binding FontSize}" 
               FontStyle="Italic" 
               Foreground="{Binding Color}" 
               FontFamily="Segoe Script" />

控件定义:

 public class CustomTextBlock : TextBlock
{
    public CustomTextBlock() : base()
    {
    }

 // THIS FAILS...BUT "NEW" IS NEVER CALLED???
    protected override void OnRender(DrawingContext drawingContext)
    {
        base.OnRender(drawingContext);

        Typeface typeface = new Typeface(this.FontFamily,
            this.FontStyle,
            this.FontWeight,
            this.FontStretch); 

        FormattedText formmatedText = new FormattedText(
            this.Text,
            System.Threading.Thread.CurrentThread.CurrentCulture,
            this.FlowDirection,
            typeface,
            this.FontSize,
            this.Foreground);

    }
}

最佳答案

无论如何我都无法弄清楚 OnRender,但这可以解决我的问题。这是一个可能的解决方案,虽然不是真正的答案。

在 UserControl 的代码隐藏中,XAML 使用 x:Name="tbc"定义了 TextBlock。

希望这对某人有帮助。

   public partial class InkStringView : UserControl
{
    public InkStringView()
    {
        InitializeComponent();           
        tbc.Loaded += new RoutedEventHandler(InkStringView_Loaded);
    }

    void InkStringView_Loaded(object sender, RoutedEventArgs e)
    {
        TextBlock tb = sender as TextBlock;

        Typeface typeface = new Typeface(
          tb.FontFamily,
          tb.FontStyle,
          tb.FontWeight,
          tb.FontStretch);

       FormattedText formattedText = new FormattedText(
            tb.Text,
            System.Threading.Thread.CurrentThread.CurrentCulture,
            tb.FlowDirection,
            typeface,
            tb.FontSize,
            tb.Foreground);

        StringViewModel svm = tb.DataContext as StringViewModel;
        svm.Bounds = formattedText.GetBoundingRect();
        svm.MidlineY1 = svm.MidlineY2 =  svm.Bounds.Top + 0.45 * (formattedText.Baseline - svm.Bounds.Top);


        double width = tb.ActualWidth;
        double height = tb.ActualHeight;

        var parent = VisualTreeHelper.GetParent(this);
        while (!(parent is Window))
        {
            parent = VisualTreeHelper.GetParent(parent);
        }


        GeneralTransform gt = tb.TransformToAncestor(parent as UIElement);
        Point offset = gt.Transform(new Point(0, 0));
        double controlTop = offset.Y;
        double controlLeft = offset.X;
    }       
}

关于c# - 如何使用 OnRender 自定义 TextBlock,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/25706684/

相关文章:

c# - 通过 Remoting/WCF 在远程计算机上部署和执行代码

c# - 我可以编写一个 C# 程序吗 - 当作为计划任务运行时 - 检测 Task Scheduler 何时试图停止它

c# - 当 ItemSource 是一个 Observable 集合时,隐藏 DataGrid 中的列

c# - 调用 View 并等到窗口关闭在 MVVM 中可行吗?

c# - 设置 Window.Content 不会破坏之前存在的 UI?

c# - 为什么我的 ASP.NET 操作寻找错误的 View ?

c# - C# 中的高精度

wpf - 使用 InvokeCommandAction MVVM 传递参数

c# - 使用 ItemSource 绑定(bind)访问 ListView 内的另一个数据上下文

wpf - 将可见性绑定(bind)到 Text.Length