【问题标题】:Sharing column width between grids defined in a template在模板中定义的网格之间共享列宽
【发布时间】:2015-03-30 20:39:31
【问题描述】:

我正在尝试布局几个控件:

浅灰色垂直线是网格分割线。此表中的每一行都是一个三列的网格,左侧是标签,中间是拆分器,右侧是控件,包括文本框和图像。

我希望所有列都对齐。这是我用于每一行的数据模板:

<DataTemplate x:Key="PropertyLineTemplate">
    <Grid Margin="0,0,0,1">
        <Grid.ColumnDefinitions>
            <ColumnDefinition SharedSizeGroup="Name"/>
            <ColumnDefinition Width="Auto"/>
            <ColumnDefinition SharedSizeGroup="Value"/>
        </Grid.ColumnDefinitions>

        <TextBlock 
            Grid.Column="0"            
            VerticalAlignment="Center"
            Text="{Binding Title}" /> 

        <GridSplitter Grid.Column="1" Width="2"/>

        <SomeUserControl
            Grid.Column="2"               
            Content="{Binding}"                
            Margin="4, 0, 0, 0"/>
    </Grid>
</DataTemplate>

以及视图本身的模板:

<DataTemplate DataType="{x:Type vm:PropertiesViewModel}">
    <DockPanel>            
        <!-- Properties -->
        <ScrollViewer>
            <StackPanel Margin="10">
                <ItemsControl ItemsSource="{Binding Properties}"
                        ItemTemplate="{StaticResource PropertyLineTemplate}" />
            </StackPanel>
        </ScrollViewer>
    </DockPanel>
</DataTemplate>

以及两者的用法:

<ContentControl Content="{Binding SelectedItem}" Grid.IsSharedSizeScope="True">          
</ContentControl>

其中SelectedItem 的类型为PropertiesViewModel

我还尝试将Grid.IsSharedSizeScope="True" 直接放置在每个单独的网格中以及包含控件的面板上,没有效果。如何实现所有列共享宽度?

【问题讨论】:

  • 为什么不直接使用 ListView GridView 并让他们拖动标题来调整列的大小?

标签: wpf layout grid


【解决方案1】:

Grid.IsSharedSizeScope 应设置在 Grid 的第一个父 ItemsControl 上,在您的情况下,它将是 ViewModel 模板中的 ItemsControl。然后将调整列宽。

但是,如果您移动一个 GridSplitter,那么它只会调整该行,而不是其他行(如果您需要调整大小,请参阅WPF SharedSizeGroup GridSplitter Issue 了解潜在的解决方案。)

其他内容:您不需要围绕 ItemsControl 的 Stackpanel 包装器,因为 ItemsControl 是唯一的孩子。如果您需要调整 ItemsControl 使用的面板,则在 Property ItemsPanel 上进行设置,如下所示:

<ItemsControl ItemsSource="{Binding Properties}"
              Grid.IsSharedSizeScope="True"
              ItemTemplate="{StaticResource PropertyLineTemplate}">
    <ItemsControl.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel/> <!-- Or <WrapPanel/> or <UniformGrid/> etc. -->
        </ItemsPanelTemplate>
    </ItemsControl.ItemsPanel>
</ItemsControl>

不过,Stackpanel 是 ItemsControl 的默认面板。

【讨论】:

  • 非常感谢,该链接有帮助。实际上我的设置是有效的,我只是不知道大小共享不支持调整大小的事实。我已经修改了您链接的主题的答案,使其更容易一些,并将其发布给可能遇到相同问题的其他人。
【解决方案2】:

根据 Nautious 的回答,我通过将两个 ColumnDefinitions 定义为资源并将所有相关列的 Width 属性绑定到这些“主列定义”的 Width 属性来解决了这个问题:

<ColumnDefinition x:Key="MasterColumnDefinition" />

<ColumnDefinition x:Key="MasterColumnDefinition2" />

<DataTemplate x:Key="PropertyLineTemplate">
     <Grid Margin="0,0,0,1">
          <Grid.ColumnDefinitions>
              <ColumnDefinition Width="{Binding Source={StaticResource MasterColumnDefinition}, Path=Width, Mode=TwoWay}"/>
              <ColumnDefinition Width="Auto"/>
              <ColumnDefinition Width="{Binding Source={StaticResource MasterColumnDefinition2}, Path=Width, Mode=TwoWay}"/>
          </Grid.ColumnDefinitions>

          ...
    </Grid>
</DataTemplate>

可能有点老套,但它很简单而且很有效。然而,这个解决方案的shared size scope 并不是定义资源的范围。 IE。将这些模板放在应用程序的资源中将导致应用程序中的所有列同步调整大小。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-08-23
    • 2016-12-09
    • 1970-01-01
    相关资源
    最近更新 更多