我有一个应用程序,我在动态地向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。)
我无法找到任何简单的方法来阻止文本的布局缩放。然而,在我开始黑客攻击解决方案之前,我想我会检查一下:有没有人知道一个干净的方法来解决这个问题?
答案 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;
}
}