我有这个案子
<WrapPanel>
<CheckBox>Really long name</CheckBox>
<CheckBox>Short</CheckBox>
<CheckBox>Longer again</CheckBox>
<CheckBox>Foo</CheckBox>
<Slider MinWidth="200" />
</WrapPanel>
我希望WrapPanel内的所有CheckBox都是相同的宽度。
添加以下内容几乎可以达到预期的效果
<WrapPanel.Resources>
<Style TargetType="CheckBox" BasedOn="{StaticResource {x:Type CheckBox}}">
<Setter Property="MinWidth" Value="75" />
</Style>
</WrapPanel.Resources>
但是,我不想硬编码特定的宽度,而是让最大的CheckBox设置宽度(如果任何宽度> 75,上面也会失败。)
Slider是独立的,应该允许比CheckBox更大。
我不想使用网格(使用IsSharedSizeScope),因为我不想要硬编码的列数。
This article提供了一个有趣的解决方案,但如果不创建自定义控件或使用C#代码就可以解决问题。
最好的方法是什么,最好只在XAML中使用?
答案 0 :(得分:8)
我最初使用IsSharedSizeGroup对此进行了调查,但遇到了障碍,使其动态应用于事物而不是显式包装项目。在这种情况下,在代码中创建AttachedProperty或其他基于代码的解决方案从长远来看可能比仅XAML方法更好。但是,要创建纯XAML解决方案,我们可以使用ColumnDefinition上的SharedSizeGroup属性来共享每个元素的大小,然后在WrapPanel上使用设置IsSharedSizeScope属性。这样做会使WrapPanel中具有相同SharedSizeGroup的所有内容共享其行的宽度和行的高度。要包装当前不在XAML中但将被添加到WrapPanel的ComboBox和可能的ComboBox,我们可以创建一个Style并重新模板化ComboBox,以便用Grid进行贝司包装。
<WrapPanel Grid.IsSharedSizeScope="True">
<WrapPanel.Resources>
<Style TargetType="{x:Type CheckBox}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type CheckBox}">
<Grid Background="LightBlue">
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="WrapPannelGroup" />
</Grid.ColumnDefinitions>
<CheckBox Style="{x:Null}"
IsChecked="{TemplateBinding IsChecked}">
<!--Other TemplateBindings-->
<CheckBox.Content>
<ContentPresenter />
</CheckBox.Content>
</CheckBox>
</Grid>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</WrapPanel.Resources>
<CheckBox>Really long name</CheckBox>
<CheckBox>Short</CheckBox>
<CheckBox IsChecked="True">Longer again</CheckBox>
<CheckBox>Foo</CheckBox>
<Slider MinWidth="200" />
</WrapPanel>
这里我们重新模板化所有CheckBoxes而没有WrapPannel中的样式,而是由Grid包围的CheckBoxes。但是,因此我们需要重新绑定我们想要维护的所有CheckBoxes属性。虽然这可能会变得很麻烦,但它也允许采用纯XAML方法。
答案 1 :(得分:1)
您可以添加执行所需工作的属性或转换器,然后将每个列的宽度绑定到它。属性或转换器可以访问整个项目列表,找到最宽的项目,并返回所有元素的所需宽度。
答案 2 :(得分:0)
执行此操作的最佳方法是使用CustomControl,就像您发布的文章一样。
您遇到的任何解决方案都必须遍历项目列表并在测量阶段找到最大宽度。
任何类型的仅XAML答案都必须提供OOTB(例如IsSharedSizeScope),或者利用某种多重绑定将项目链接在一起。因此,任何类型的XAML答案都会充满标记,这使得它更加冗长(并且不那么优雅)。
我在您发布的CodeProject文章中看到的唯一修改是添加了“关闭”某些元素(如滑块)的能力。这可以作为附加附加财产来完成。