我在 Style 触发器中更改了 Text 的 FontSize,这会导致包含文本的 Control 也调整大小。如何在不影响父级大小的情况下更改字体大小?
6 回答
明智地将元素与其父布局隔离的一个好技巧是将元素放置在 Canvas 中
在下面的标记中,您的元素有两个副本 第一个是隐藏的并确定控件的大小 第二个是可见的,但包裹在 Canvas 中,因此其布局大小不会影响父级。
<Parent>
<Grid>
<Element Visibility="Hidden"/>
<Canvas>
<Element />
</Canvas>
<Grid>
</Parent>
绝对不需要硬编码的宽度、疯狂的度量覆盖、棘手的绑定或任何类似的东西。
解决方案实际上非常简单。不要在样式触发器中更改字体大小,而是为您的按钮创建一个简单的控件模板,并将 RenderTransform 应用于内容呈现器元素。将 ScaleTransform 添加到 RenderTransform。在 IsPressed 触发器定义中,将 ScaleTransform 上的垂直和水平比例设置为较小的比率,例如 0.8。
使用 RenderTransform 将保持按下按钮的布局相同,因此不会影响其他元素的位置。相比之下,使用 LayoutTransform 实际上会导致按钮容器缩小,而父容器的 ArrangeOverride 方法会导致相邻按钮移动以填充额外空间。
我现在真的很忙,所以我将把实际的实施留给你!;-)
http://msdn.microsoft.com/en-us/library/system.windows.media.scaletransform.aspx
您可以在减小 FontSize 的同时增加 Padding - 这将导致 Button 的计算高度保持不变:
<StackPanel>
<Button Content="ABC">
<Button.Style>
<Style TargetType="{x:Type Button}">
<Setter Property="FontSize" Value="20"/>
<Style.Triggers>
<Trigger Property="IsPressed" Value="True">
<Setter Property="FontSize" Value="12"/>
<Setter Property="Padding" Value="5"/>
</Trigger>
</Style.Triggers>
</Style>
</Button.Style>
</Button>
<Button Margin="0,20" Content="123" FontSize="20"/>
<Button Content="Do Re Mi" FontSize="20"/>
</StackPanel>
如果 FontSize 也在增加,您也可以反过来设置负填充。
您还可以使用从 FontSize 到 Padding 的绑定以一般方式完成相同的事情,但如果您只处理一组固定的 FontSizes,那么像上面那样对它进行硬编码会更容易。
我正在为 ButtonControl 创建一个 ControlTemplate,因此它看起来像一个带有 IsKeyboardFocused、IsPressed、IsDefaulted 等触发器的标签(平面文本,无边框)。
IsPressed 被定义为将 FontSize(从默认值 30)降低到 28。以提供按下的动画效果。
这些 Button 的一种用途是 Button 的水平 StackPanel,由垂直分隔符分隔。当 IsPressed 触发器在按钮上触发并调整大小时,整行按钮都会重新调整,这不是令人愉悦的视觉效果。
我的偏好是基于模板的解决方案,以避免引入新控件以提供覆盖。硬编码大小方法的唯一问题是国际化,其他语言会增加原始大小。
我要使用的解决方案是在计算完按钮的 DesiredSize 后在 C# 中设置 minWidth。请注意,即使在呈现 Button 之后,宽度也是 NaN,因此 DesiredSize 的使用/存在。稍后我将尝试对 C# 进行 XAML 化。
你使用什么样的控件?如果这是像 GroupBox 或 TabItem 这样的 HeaderedControl,那么您需要专门设置 HeaderTemplate,如下所示:
<DataTemplate x:Key="MyHeaderTemplate">
<TextBlock Text="{Binding}" Fontsize="14" FontWeight="Bold" />
</DataTemplate>
我可以想到一些你可以尝试的事情:
您可以覆盖控件的 Measure Pass - 在 WPF 中呈现控件时,它会经历两次传递。第一个是“测量通过”,控件提出它想要的尺寸。第二个是“安排通行证”,它实际上布置了控制。WPF 提供了一种称为MeasureOverride 的方法。如果您重写此方法,您可以提供可用于调整控件大小的自定义行为。
注意- 我相信您必须在此覆盖期间调用所有控件子项的 Measure 方法,以使您的控件正确布局。
硬编码控件上的高度和宽度- 这将使用您的值覆盖控件的 DesiredSize。虽然通常不是最好的想法,但它会起作用。