如何使 RadioButton 的项目符号顶部对齐?
我有一个多行单选按钮,我希望项目符号位于内容的左侧(默认情况下)与单选按钮控件的顶部对齐。 在 XAML 中执行此操作的最简单方法是什么?
I have a multiline radio button and I want the bullet to be to the left of the content (as default) aligned to the top of the radio button control. What's the easiest way to do this in XAML?
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
我基于 Simon Weaver 的答案构建了一个相对通用的模板,可以在大多数情况下使用,而无需记住自定义始终是您的
RadioButton.Content
。解释模板的工作原理:
TextBlock
之所以存在,是因为默认情况下,如果内容是 Text 对象(Label
),RadioButton 项目符号会与 Text 的第一行对齐code> 不起作用)LineBreak
是将内容换行,因此创建第一行InlineUIContainer
,以便我们可以将非文本内容放入TextBlock
ContentPresenter
是用来保存实际内容的,它有一个负数上边距用于删除LineBreak
对象留下的空格。这是一些示例内容:
以及它的外观:
我唯一真正不满意的是
ContentPresenter
的负上边距被硬编码,因为如果您更改字体大小,则必须手动调整该边距。为
Margin
属性构建一个转换器来计算换行符的高度({TemplateBinding FontSize}
?),甚至是扩展默认情况下具有此行为的 RadioButton 控件的版本,但现在我可以根据应用程序的默认字体大小硬编码 -21。另外,如果您想从原始
RadioButton
继承其他属性,您可能需要向模板中的RadioButton
添加一些TemplateBindings
,例如边距、填充、对齐等。为了保持简单,我只绑定到IsChecked
。I've built a relatively generic template based on Simon Weaver's answer that can be used in most situations without having to remember to customize your
RadioButton.Content
all the time.To explain how the template works:
The
TextBlock
is there because by default, the RadioButton bullet aligns with the first line of Text if the content is a Text object (aLabel
will not work)The
LineBreak
is to wrap the content to a new line, so the first line is createdThe
InlineUIContainer
is so we can place non-text content into aTextBlock
The
ContentPresenter
is to hold the actual content, and it has a negative top margin to remove the space left by theLineBreak
object.Here's some example content:
And how it looks:
The only thing I'm really not happy about is the negative top margin for the
ContentPresenter
being hard-coded, because if you ever change your font size, you have to manually adjust that margin.It probably wouldn't be that hard to build a converter for the
Margin
property that calculates the height of the line break ({TemplateBinding FontSize}
?), or even an extended version of the RadioButton control which has this behavior by default, but for now I'm fine with hard-coding -21 based on my application's default font size.Also, you might want to add some
TemplateBindings
to theRadioButton
in the Template if you want to inherit other properties from the originalRadioButton
, such as margins, padding, alignment, etc. I only bound toIsChecked
for the purpose of keeping it simple.覆盖 RadioButton 的 Control.Template。 以下是来自 MSDN 单选按钮控件模板示例的示例,
如果您不这样做不想覆盖单选按钮的 Control.Template,您可以将内容设为 Wrapped TextBlock。 看这个样本
Override the Control.Template for the RadioButton. Here is the example from MSDN Radio Button Control Template Example
If you don't want to override the Control.Template for the radio button you can make the content a Wrapped TextBlock. see this sample
注意:请务必查看Rachel 的回答 - 她将这一阶段进一步转化为通用的template
首先,不要在
VerticalAlignment
或VerticalContentAlignment
(甚至ControlTemplate
)上浪费时间。 他们不会做你想要或可能期望的事。如 MSDN 一个
BulletDecorator
(这是 CheckBox 和 RadioButton 用于呈现单选/复选按钮的控件)将自动设置图标的位置。 您对此没有额外的控制权:除非您更改控件模板(不必要),否则您只能在内容是文本的情况下将单选/复选图标放置在顶部。
因此,如果您执行类似的操作,它看起来不会很好,因为无论您尝试设置多少个
VerticalAlignment
属性,您都将无法移动图标。但是幸运的是,您可以使用
InlineUIContainer
将几乎所有您想要的东西放入TextBlock
中。 第一行中的文本(或内容)将自动指示图标的位置。 如果您想要第一行下面的内容不是文本,只需使用
,然后使用这里有一个示例,其中包含超大的
TextBox
可以更清楚地显示正在发生的情况。Note: Be sure to check out Rachel's answer - she takes this one stage further into a generic template
First of all don't waste your time with
VerticalAlignment
orVerticalContentAlignment
(or evenControlTemplate
). They're not going to do what you want or might expect.As described on MSDN a
BulletDecorator
(which is the control that CheckBox and RadioButton uses to render a radio/check button) will set the position of the icon automatically. You have no additional control over this:Unless you change the control template (unnecessary) you'll only be able to position the radio/check icon at the top if the content is text.
So if you do something like this it won't look good because you won't be able to move the icon no matter how many
VerticalAlignment
properties you try to set.BUT fortunately you can put pretty much anything you want in a
TextBlock
usingInlineUIContainer
. The text (or content) in the first line will dictate the position of the icon automatically. If you want something underneath the first line that isn't text, just use<Linebreak/>
and then<InlineUIContainer/>
Here's an example that has an oversized
TextBox
to show more clearly what's happening.