由于LayoutTransform,阻止WPF TextBlock扩展文本

时间:2012-08-24 23:07:29

标签: .net wpf xaml

我有一个应用程序,我在动态地向Canvas添加各种实例,底层Canvas有一个缩放LayoutTransform。这适用于像矩形这样的视觉效果,它们可以正确地保持固定的笔触宽度,但在使用LayoutTransform“缩放”画布时,可以扩展形状宽度/高度。但是,对于TextBlock实例,布局转换实际上是缩放文本的渲染,使字体有效地变大。我希望发生的是TextBlock的左上角原点与布局转换一起翻译,文本保持相同的大小。

以下是创建Canvas的ItemsControl的XAML:

            <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>

以下是一些从绑定集合中呈现Annotations的数据模板:

    <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>

Annotation实例本身是简单的INotifyPropertyChanged实现,具有相关的绑定属性(TextXnnotation的StartX,StartY和Text。)

我无法找到任何简单的方法来阻止文本的布局缩放。然而,在我开始黑客攻击解决方案之前,我想我会检查一下:有没有人知道一个干净的方法来解决这个问题?

2 个答案:

答案 0 :(得分:2)

每个变换都有一个反转属性,可以解除其影响。因此,您可以将TextBlock的RenderTransform绑定到Transform的Inverse,它会缩放Canvas,它应该撤消对文本渲染的影响。

左上角通常是缩放的原点,因此如果all都是默认值,则Text应按指定的方式移动到左上角。但是,如果您在画布上使用组合变换或不同的缩放中心,则可能需要稍微调整一下参数,但它应该非常容易。编写一个只采用变换比例因子的转换器,以便在不改变变焦中心的情况下创建反比例变换。

答案 1 :(得分:0)

我无法绑定到Inverse,正如@hbarck建议的那样,因为这是一个GeneralTransform而不是Transform。我通过按元素名称绑定到ScaleTransform并使用值转换器来反转缩放来解决这个问题:

    <Controls:InvertConverter x:Key="Invert"/>
    <DataTemplate DataType="{x:Type Annotations:TextAnnotation}">
        <TextBlock Text="{Binding Text}" Foreground="Orange" IsHitTestVisible="False">
            <TextBlock.RenderTransform>
                <ScaleTransform ScaleX="{Binding ScaleX, ElementName=AnnotationScale, Converter={StaticResource Invert}}"
                                ScaleY="{Binding ScaleY, ElementName=AnnotationScale, Converter={StaticResource Invert}}"/>
            </TextBlock.RenderTransform>
        </TextBlock>
    </DataTemplate>

以下转换器代码:

public sealed class InvertConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.GetType() != typeof(double) || targetType != typeof(double))
            return null;

        return 1/(double)value;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || value.GetType() != typeof(double) || targetType != typeof(double))
            return null;

        return 1 / (double)value;
    }
}