4

我有这个案例

<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 是独立的,应该允许大于 CheckBoxes。

我不想使用网格(带有 IsSharedSizeScope),因为我不想要硬编码的列数。

本文提出了一个有趣的解决方案,但如果不创建自定义控件或使用 C# 代码来解决该问题会很好。

最好的方法是什么,最好只在 XAML 中?

4

3 回答 3

9

我最初使用 IsSharedSizeGroup 来查看这个,但遇到了一个障碍,使其动态应用于事物而不是显式包装项目。在这种情况下,从长远来看,在代码或其他基于代码的解决方案中创建 AttachedProperty 可能比仅使用 XAML 的方法更好。但是,要创建纯粹的 XAML 解决方案,我们可以使用ColumnDefinition 上的SharedSizeGroup属性来共享每个元素的大小,然后使用设置IsSharedSizeScopeWrapPanel 上的属性。这样做将使 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>

在这里,我们将 WrapPannel 内没有样式的所有 CheckBox 重新模板化为被 Grid 包围的 CheckBox。然而,正因为如此,我们需要重新绑定我们想要维护的所有 CheckBoxes 属性。虽然这可能会变得繁重,但它也允许使用纯 XAML 方法。

于 2009-06-24T14:07:11.480 回答
1

您可以添加执行所需工作的属性或转换器,然后将每列的宽度绑定到它。属性或转换器可以访问整个项目列表,找到最宽的项目,并返回所有元素的所需宽度。

于 2009-06-24T17:26:45.480 回答
0

最好的方法是使用像您发布的文章一样的 CustomControl。

您遇到的任何解决方案都必须遍历项目列表并在测量阶段找到最大宽度。

必须提供任何类型的仅 XAML 答案 OOTB(例如 IsSharedSizeScope),或者将利用某种多绑定将项目链接在一起。因此,任何类型的 XAML 答案都将充满标记,这使得它更加冗长(并且不那么优雅)。

我看到的对您发布的 CodeProject 文章的唯一修改是添加了“关闭”对某些元素(如滑块)的考虑的能力。这可以作为附加的附加属性来完成。

于 2009-06-24T18:07:52.600 回答