prevent WPF的TextBlock从文本扩展因LayoutTransform文本、WPF、prevent、LayoutTransform

2023-09-04 04:08:16 作者:海盐苏打

我在哪里,我加入各种实例来画布动态应用程序和下层的画布将有一定LayoutTransform。这对于像矩形,在那里他们正确地保持一个固定的描边宽度,但扩大的形状宽/高为画布'放大'与LayoutTransform视觉的伟大工程。对于TextBlock的实例,然而,布局转换实际上是缩放文本的渲染,使得字体有效大。我想有发生,而不是对文本块的左上角起源与布局转换翻译,与其余相同大小的文本。

I have an application where I am adding various instances to a Canvas dynamically and the underlying Canvas has a scaling LayoutTransform. This works great for visuals like rectangles, where they correctly maintain a fixed stroke width, but expand in shape width/height as the canvas is 'zoomed' with the LayoutTransform. For TextBlock instances, however, the layout transformation is actually scaling the rendering of the text, making the font effectively larger. What I'd like to have happen instead is for the upper left origin of the TextBlock to translate with the layout transformation, with the text remaining the same size.

下面是XAML的ItemsControl的创建画布:

Here is the XAML for the ItemsControl that creates the Canvas:

            <ItemsControl ItemsSource="{Binding Annotations}">
                <ItemsControl.ItemsPanel>
                    <ItemsPanelTemplate>
                        <Canvas />
                    </ItemsPanelTemplate>
                </ItemsControl.ItemsPanel>
                <ItemsControl.ItemContainerStyle>
                    <Style>
                        <Setter Property="Canvas.Left" Value="{Binding StartX}"/>
                        <Setter Property="Canvas.Top" Value="{Binding StartY}"/>                            
                    </Style>
                </ItemsControl.ItemContainerStyle>
                <ItemsControl.LayoutTransform>
                    <TransformGroup>
                        <ScaleTransform ScaleX="{Binding ZoomScale}" ScaleY="{Binding ZoomScale}" 
                                        CenterX="0.5" CenterY="0.5"/>
                    </TransformGroup>
                </ItemsControl.LayoutTransform>
            </ItemsControl>

下面是一些渲染从绑定集合的注释的数据模板:

Here are some of the data templates that render the Annotations from the bound collection:

    <DataTemplate DataType="{x:Type Annotations:RectangleAnnotation}">
        <Rectangle Width="{Binding Width}" Height="{Binding Height}" Stroke="Blue" IsHitTestVisible="False"/>
    </DataTemplate>

    <DataTemplate DataType="{x:Type Annotations:TextAnnotation}">
        <TextBlock Text="{Binding Text}" Foreground="Orange" IsHitTestVisible="False"/>
    </DataTemplate>

在注释实例本身很简单INotifyPropertyChanged的实施有关绑定属性(STARTX,StartY和文本的TextAnnotation。)

The Annotation instances themselves are simple INotifyPropertyChanged implementations with the relevant bound properties (StartX, StartY and Text for the TextAnnotation.)

我一直没能找到任何简单的方法来prevent文本的布局比例。然而,在我开始黑客我的方式来解决,我想我会检查:没有任何人知道的一个干净的方式来解决这个问题。

I haven't been able to find any easy way to prevent the layout scaling of the text. However, before I start hacking my way to a solution, I thought I'd check: does anybody know of a clean way to fix this?

推荐答案

每一个转换有一个逆向性,解除其效果。所以,你可以文本块的的RenderTransform结合的变换而缩放画布的反向,应撤消其对文本的渲染效果。

Every Transform has an Inverse property which undoes its effect. So, you can bind the TextBlock's RenderTransform to the Inverse of the Transform which scales the Canvas, that should undo its effect on the text rendering.

左上角通常为原点用于缩放,所以如果所有的默认,作为所指定的文本应该移动到的左上角。不过,如果你使用的是组合变换或画布上的一个不同的缩放中心,您可能必须与参数周围玩了一下,但它应该是很容易的,例如写一个转换器,它只需一个比例因子,以便创造一个逆尺度变换不移位变焦中心变换。

The upper left corner normally is the origin for scaling, so if all is default, the Text should move to the upper left corner as you specified. However, if you're using combined transforms or a different zoom center on the canvas, you might have to play around with the parameters a bit, but it should be quite easy to e.g. write a converter which only takes the scale factors of a transform in order to create an inverse scale transform without shifting the zoom center.