带样式的 ListBox 中 ContentControl 的垂直对齐
Vertical alignment of ContentControl in styled ListBox
我正在使用 this answer 将 ListBox
设置为 RadioButton
的样式,以便通过枚举驱动选中的单选按钮的选择来简化我的 MVVM 代码 - 而不是让一堆我必须手动来回映射到枚举的布尔值。
当 ListBoxItem
内容是一行简单的文本时,这非常有效。单选按钮与文本对齐,一切顺利。但是,当我将内容更改为 UserControl
时,该选项的单选按钮会呈现在 UserControl
的垂直中点,而不是顶部(我想要的位置)。
这是一些代码和一张图片,可以更好地解释我正在尝试做的事情(请注意,为清楚起见,省略了很多内容):
我将作为内容插入其中一个选项的 UserControl
<UserControl x:Class="TestCtl">
<StackPanel Orientation="Vertical" >
<Label Margin="-5,0,0,0" Content="Choice #2"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
</UserControl>
ListBox
(在别处定义了上述样式)
<StackPanel Orientation="Vertical">
<ListBox SelectedValuePath="Tag"
Style="{StaticResource RadioButtonList}"
SelectedValue="{Binding Blah Blah"}>
<ListBoxItem Tag="Choice1" Content="Choice #1" />
<ListBoxItem Tag="Choice2">
<ContentControl>
<subf:TestCtl />
</ContentControl>
</ListBoxItem>
<ListBoxItem Tag="Choice3" Content="Choice #3"/>
<ListBoxItem Tag="Choice4" Content="Choice #4" />
</ListBox>
<ComboBox blah blah/>
</StackPanel>
渲染后的样子:
我已经尝试设置 VerticalAlignment
和 VerticalContentAlignment
以及在我的 xaml 代码和我链接到的样式,但无论我设置什么,我都无法让单选按钮和用户控件在它们的顶部对齐。
有没有办法通过修改我正在使用的样式或我的代码来实现我想要的?还是我完全错了?
将 Label
的 Padding
设置为 0
:
<ListBoxItem Tag="Choice1" Content="Choice #1" />
<ListBoxItem Tag="Choice2">
<UserControl>
<StackPanel Orientation="Vertical" >
<Label Content="Choice #2" Padding="0"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
</UserControl>
</ListBoxItem>
<ListBoxItem Tag="Choice3" Content="Choice #3"/>
<ListBoxItem Tag="Choice4" Content="Choice #4" />
这应该可以解决垂直对齐问题。但是您不必首先使用 ListBox
就能够将 RadioButton
绑定到单个来源 属性:
在 RabioButtonList 样式中更改为:
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderThickness="0" Background="Transparent">
<!-- CHANGE THIS -->
<StackPanel Orientation="Horizontal">
<RadioButton
Focusable="False"
IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}"/>
<ContentPresenter />
</StackPanel>
<!------------------>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
在用户控件中将标签 Padding 设置为 5,0,0,0(感谢 mm8)
<StackPanel Orientation="Vertical" >
<Label Margin="-5,0,0,0" Content="Choice #2" Padding="5,0,0,0"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
我正在使用 this answer 将 ListBox
设置为 RadioButton
的样式,以便通过枚举驱动选中的单选按钮的选择来简化我的 MVVM 代码 - 而不是让一堆我必须手动来回映射到枚举的布尔值。
当 ListBoxItem
内容是一行简单的文本时,这非常有效。单选按钮与文本对齐,一切顺利。但是,当我将内容更改为 UserControl
时,该选项的单选按钮会呈现在 UserControl
的垂直中点,而不是顶部(我想要的位置)。
这是一些代码和一张图片,可以更好地解释我正在尝试做的事情(请注意,为清楚起见,省略了很多内容):
我将作为内容插入其中一个选项的 UserControl
<UserControl x:Class="TestCtl">
<StackPanel Orientation="Vertical" >
<Label Margin="-5,0,0,0" Content="Choice #2"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
</UserControl>
ListBox
(在别处定义了上述样式)
<StackPanel Orientation="Vertical">
<ListBox SelectedValuePath="Tag"
Style="{StaticResource RadioButtonList}"
SelectedValue="{Binding Blah Blah"}>
<ListBoxItem Tag="Choice1" Content="Choice #1" />
<ListBoxItem Tag="Choice2">
<ContentControl>
<subf:TestCtl />
</ContentControl>
</ListBoxItem>
<ListBoxItem Tag="Choice3" Content="Choice #3"/>
<ListBoxItem Tag="Choice4" Content="Choice #4" />
</ListBox>
<ComboBox blah blah/>
</StackPanel>
渲染后的样子:
我已经尝试设置 VerticalAlignment
和 VerticalContentAlignment
以及在我的 xaml 代码和我链接到的样式,但无论我设置什么,我都无法让单选按钮和用户控件在它们的顶部对齐。
有没有办法通过修改我正在使用的样式或我的代码来实现我想要的?还是我完全错了?
将 Label
的 Padding
设置为 0
:
<ListBoxItem Tag="Choice1" Content="Choice #1" />
<ListBoxItem Tag="Choice2">
<UserControl>
<StackPanel Orientation="Vertical" >
<Label Content="Choice #2" Padding="0"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>
</UserControl>
</ListBoxItem>
<ListBoxItem Tag="Choice3" Content="Choice #3"/>
<ListBoxItem Tag="Choice4" Content="Choice #4" />
这应该可以解决垂直对齐问题。但是您不必首先使用 ListBox
就能够将 RadioButton
绑定到单个来源 属性:
在 RabioButtonList 样式中更改为:
<Setter Property="ItemContainerStyle">
<Setter.Value>
<Style TargetType="{x:Type ListBoxItem}" >
<Setter Property="Margin" Value="5" />
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type ListBoxItem}">
<Border BorderThickness="0" Background="Transparent">
<!-- CHANGE THIS -->
<StackPanel Orientation="Horizontal">
<RadioButton
Focusable="False"
IsHitTestVisible="False"
IsChecked="{TemplateBinding IsSelected}"/>
<ContentPresenter />
</StackPanel>
<!------------------>
</Border>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</Setter.Value>
</Setter>
在用户控件中将标签 Padding 设置为 5,0,0,0(感谢 mm8)
<StackPanel Orientation="Vertical" >
<Label Margin="-5,0,0,0" Content="Choice #2" Padding="5,0,0,0"/>
<CheckBox Margin="10,0,0,5">Option 1</CheckBox>
<CheckBox Margin="10,0,0,5">Option 2</CheckBox>
<CheckBox Margin="10,0,0,0">Option 3</CheckBox>
</StackPanel>