WPF 样式触发器
声明:本页面是StackOverFlow热门问题的中英对照翻译,遵循CC BY-SA 4.0协议,如果您需要使用它,必须同样遵循CC BY-SA许可,注明原文地址和作者信息,同时你必须将它归于原作者(不是我):StackOverFlow
原文地址: http://stackoverflow.com/questions/321701/
Warning: these are provided under cc-by-sa 4.0 license. You are free to use/share it, But you must attribute it to the original authors (not me):
StackOverFlow
WPF Style Trigger
提问by Aidan
I change the FontSize of Text in a Style trigger, this causes the Control containing the text to resize as well. How can I change the Fontsize without affecting the parent's size?
我在样式触发器中更改了文本的字体大小,这会导致包含文本的控件也调整大小。如何在不影响父级大小的情况下更改字体大小?
回答by Ifeanyi Echeruo
A nice trick to isolate an element from its parent layout wise is to place the element in a Canvas
将元素与其父布局隔离的一个很好的技巧是将元素放置在 Canvas 中
In the markup below there are two copies of your element The first is hidden and establishes the size of your control The second is visible but wrapped in a Canvas so its layout size does not affect the parent.
在下面的标记中,您的元素有两个副本 第一个是隐藏的,并确定您的控件的大小 第二个是可见的,但包裹在 Canvas 中,因此其布局大小不会影响父级。
<Parent>
<Grid>
<Element Visibility="Hidden"/>
<Canvas>
<Element />
</Canvas>
<Grid>
</Parent>
回答by Ifeanyi Echeruo
There is absolutely NO need for hard-coded widths, crazy measure overrides, tricky bindings, or anything of that sort.
绝对不需要硬编码宽度、疯狂的度量覆盖、棘手的绑定或任何类似的东西。
The solution is actually incredibly simple. Instead of changing the font size in a style trigger, create a simple control template for your button with a RenderTransform applied to the content presenter element. Add a ScaleTransform to the RenderTransform. Inside a IsPressed trigger definition set the vertical and horizontal scales on the ScaleTransform to a smaller ratio, say 0.8.
解决方案实际上非常简单。不要在样式触发器中更改字体大小,而是为您的按钮创建一个简单的控件模板,并将 RenderTransform 应用于内容展示器元素。将 ScaleTransform 添加到 RenderTransform。在 IsPressed 触发器定义中,将 ScaleTransform 上的垂直和水平比例设置为较小的比例,例如 0.8。
Using a RenderTransform will keep the layout of the pressed button the same with, so it won't influence the position of the other elements. By contrast, using a LayoutTransform would have actually caused the button container to shrink and the parent container's ArrangeOverride method would cause the adjacent buttons to move to fill the extra space.
使用 RenderTransform 将使按下的按钮的布局保持相同,因此不会影响其他元素的位置。相比之下,使用 LayoutTransform 实际上会导致按钮容器缩小,而父容器的ArrangeOverride 方法会导致相邻按钮移动以填充额外的空间。
I'm really busy right now so I'll leave the actual implementation up to you! ;-)
我现在真的很忙,所以我会把实际的实现留给你!;-)
http://msdn.microsoft.com/en-us/library/system.windows.media.scaletransform.aspx
http://msdn.microsoft.com/en-us/library/system.windows.media.scaletransform.aspx
回答by Robert Macnee
You can increase the Padding at the same time you decrease the FontSize - this will cause the calculated height of the Button to remain the same:
您可以在减少 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>
You can do the reverse and set a negative Padding if the FontSize is increasing, as well.
如果 FontSize 增加,您也可以反向操作并设置负 Padding。
You could also use a binding from FontSize to Padding to accomplish the same thing in a general way, but if you're only dealing with a fixed set of FontSizes it would be easier to just hardcode it as above.
您还可以使用从 FontSize 到 Padding 的绑定以一般方式完成相同的事情,但是如果您只处理一组固定的 FontSizes,那么像上面那样对其进行硬编码会更容易。
回答by Aidan
I am creating a ControlTemplate for a ButtonControl so it looks like a label (flat text, no borders) with triggers for IsKeyboardFocused, IsPressed, IsDefaulted etc.
我正在为 ButtonControl 创建一个 ControlTemplate,因此它看起来像一个带有 IsKeyboardFocused、IsPressed、IsDefaulted 等触发器的标签(纯文本,无边框)。
The IsPressed is defined to drop the FontSize (from default of 30) down to 28. To give a pressed animation effect.
IsPressed 定义为将 FontSize(从默认值 30)降低到 28。以提供按下的动画效果。
One use of these Buttons is a horizontal StackPanel of Button, separated by vertical separators. When the IsPressed trigger is fired on a button and it is resized, the entire row of buttons gets re adjusted, which is not a pleasing visual effect.
这些 Button 的一种用途是 Button 的水平 StackPanel,由垂直分隔符分隔。当在按钮上触发 IsPressed 触发器并调整其大小时,整行按钮都会重新调整,这不是令人愉悦的视觉效果。
My preference is for a template based solution, to avoid introducing new controls in order to provide overrides. The only problem with the hard coded size approach is internationalisation, other languages will increase the orginal size.
我更喜欢基于模板的解决方案,以避免引入新控件以提供覆盖。硬编码大小方法的唯一问题是国际化,其他语言会增加原始大小。
The solution I am going with is to set the minWidth in C# after the button's DesiredSize has been calculated. Note that Width is NaN even after the Button is rendered hence the use/existence of DesiredSize. Later I will try and XAMLize the C#.
我要使用的解决方案是在计算按钮的 DesiredSize 后在 C# 中设置 minWidth。请注意,即使在呈现按钮之后,宽度也是 NaN,因此使用/存在 DesiredSize。稍后我将尝试 XAMLize C#。
回答by Micah
What kind of control are you using? If this is a HeaderedControl like a GroupBox or TabItem then you need to specifically set the HeaderTemplate like this:
你用的是什么控件?如果这是一个像 GroupBox 或 TabItem 这样的 HeaderedControl 那么你需要像这样专门设置 HeaderTemplate:
<DataTemplate x:Key="MyHeaderTemplate">
<TextBlock Text="{Binding}" Fontsize="14" FontWeight="Bold" />
</DataTemplate>
回答by NigelTufnel
I can think of a couple of things you could try:
我可以想到一些你可以尝试的事情:
You can override the Measure Pass of the control- when a control is rendered in WPF it undergoes two passes. The first is a 'measure pass', where the control comes up with what sizes that it wants to be. The second is the 'arrange pass', where it actually lays out the control. WPF provides a method called MeasureOverride.If you override this method you can provide custom behavior that can be used to adjust the size of the control.
Note- I believe that you will have to call the Measure method all of your controls children during this override in order to get your control to lay out properly.
Hard code the height and width on the control- this will override the control's DesiredSize with your values. While generally a not the greatest of ideas, it will work.
您可以覆盖控件的 Measure Pass- 当在 WPF 中呈现控件时,它会经历两次传递。第一个是“测量通过”,其中控件提出它想要的尺寸。第二个是“安排传递”,它实际上布置了控制。WPF 提供了一种称为MeasureOverride的方法。如果覆盖此方法,则可以提供可用于调整控件大小的自定义行为。
注意- 我相信您必须在此覆盖期间调用所有控件子项的 Measure 方法,以使您的控件正确布局。
对控件的高度和宽度进行硬编码- 这将使用您的值覆盖控件的 DesiredSize。虽然通常不是最伟大的想法,但它会奏效。