【问题标题】:Silverlight 3 BETA DataGrid groupingSilverlight 3 BETA DataGrid 分组
【发布时间】:2010-11-09 14:53:58
【问题描述】:

注意,这是针对 silverlight 3 beta 的,RTM 处理分组的方式似乎完全不同。

我有一个工作正常的网格,我正在使用 GroupDescriptions 属性,如下所示:

<data:DataGrid.GroupDescriptions>
    <cm:PropertyGroupDescription PropertyName="ClientName" />
</data:DataGrid.GroupDescriptions>

这非常有效,只有在渲染数据网格时,它才会显示按“ClientName”进行的分组。显然,我希望它是“客户名称”。我一辈子都看不到允许我设置它的属性吗?

【问题讨论】:

    标签: silverlight silverlight-3.0 datagrid


    【解决方案1】:

    FWIW 这在 SL3 RTM 中有所改变:

    Silverlight 3 测试版

    [Xaml]

    <dataGrid.GroupDescriptions>
    
          <windata:PropertyGroupDescription PropertyName=”State” />
    
    </dataGrid.GroupDescriptions>
    

    银光 3 RTM

    [c#]

    pagedCollectionView.GroupDescriptions.Add(new PropertyGroupDescription(“State”));
    

    您需要使用 PagedCollectionView 类来完成此操作,它不能在 Xaml 中完成。见http://msdn.microsoft.com/en-us/library/dd833072(VS.95).aspx

    通过该链接,以下是更改组标题中文本的方法:

    当项目在 DataGrid 中分组时,每个组都有一个标题。您可以通过定义自定义样式并将其添加到 RowGroupHeaderStyles 集合来更改 DataGridRowGroupHeader 的外观。如果您有多个分组级别,您可以将不同的样式应用于每个分组级别。样式按照定义的顺序应用。例如,如果您定义了两种样式,则第一种将应用于顶级行组。第二种样式将应用于第二级及更低级别的所有行组。 DataGridRowGroupHeader的DataContext就是header代表的CollectionViewGroup。

    所以一个快速而肮脏的例子是:

    <dataControls:DataGrid x:Name="Grid">
        <dataControls:DataGrid.RowGroupHeaderStyles>
            <Style TargetType="dataControls:DataGridRowGroupHeader">
                <Setter Property="Template">
                    <Setter.Value>
                        <ControlTemplate>
                            <TextBlock Text="My text."/>
                        </ControlTemplate>
                    </Setter.Value>
                </Setter>
            </Style>
       </dataControls:DataGrid.RowGroupHeaderStyles>
    </dataControls:DataGrid>
    

    实际上,您可能希望包含为 DataGridRowGroupHeader 指定的其他控件部分,以便您可以展开和折叠它们。与 WPF 的所有内容一样,您不仅要设置“GroupText”属性,还必须走完整的 9 码!

    【讨论】:

    • 什么是分页集合视图?我尝试使用 CollectionViewSource,但未实现 GroupDescriptions 属性。
    【解决方案2】:

    遇到与 DaRKoN_ 相同的问题并阅读了 James Cadd 有见地的答案后,我解决了自己的问题。通过使用 Blend,我提取了 DataGridRowGroupHeader 的模板。您可以使用下面的代码来自定义它:

    <data:DataGrid>
      <data:DataGrid.RowGroupHeaderStyles>
        <Style TargetType="data:DataGridRowGroupHeader">
          <Setter Property="Template">
            <Setter.Value>
              <ControlTemplate TargetType="data:DataGridRowGroupHeader">
                <dataPrimitives:DataGridFrozenGrid x:Name="Root" Background="{TemplateBinding Background}">
                  <dataPrimitives:DataGridFrozenGrid.Resources>
                    <ControlTemplate x:Key="ToggleButtonTemplate" TargetType="ToggleButton">
                      <Grid Background="Transparent">
                        <VisualStateManager.VisualStateGroups>
                          <VisualStateGroup x:Name="CommonStates">
                            <VisualState x:Name="Normal"/>
                            <VisualState x:Name="MouseOver">
                              <Storyboard>
                                <ColorAnimation Duration="0" Storyboard.TargetName="CollapsedArrow" Storyboard.TargetProperty="(Stroke).Color" To="#FF6DBDD1"/>
                                <ColorAnimation Duration="0" Storyboard.TargetName="ExpandedArrow" Storyboard.TargetProperty="(Fill).Color" To="#FF6DBDD1"/>
                              </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Pressed">
                              <Storyboard>
                                <ColorAnimation Duration="0" Storyboard.TargetName="CollapsedArrow" Storyboard.TargetProperty="(Stroke).Color" To="#FF6DBDD1"/>
                                <ColorAnimation Duration="0" Storyboard.TargetName="ExpandedArrow" Storyboard.TargetProperty="(Fill).Color" To="#FF6DBDD1"/>
                              </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Disabled">
                              <Storyboard>
                                <DoubleAnimation Duration="0" Storyboard.TargetName="CollapsedArrow" Storyboard.TargetProperty="Opacity" To=".5"/>
                                <DoubleAnimation Duration="0" Storyboard.TargetName="ExpandedArrow" Storyboard.TargetProperty="Opacity" To=".5"/>
                              </Storyboard>
                            </VisualState>
                          </VisualStateGroup>
                          <VisualStateGroup x:Name="CheckStates">
                            <VisualState x:Name="Checked"/>
                            <VisualState x:Name="Unchecked">
                              <Storyboard>
                                <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="CollapsedArrow" Storyboard.TargetProperty="Visibility">
                                  <DiscreteObjectKeyFrame KeyTime="0" Value="Visible"/>
                                </ObjectAnimationUsingKeyFrames>
                                <ObjectAnimationUsingKeyFrames Duration="0" Storyboard.TargetName="ExpandedArrow" Storyboard.TargetProperty="Visibility">
                                  <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed"/>
                                </ObjectAnimationUsingKeyFrames>
                              </Storyboard>
                            </VisualState>
                          </VisualStateGroup>
                        </VisualStateManager.VisualStateGroups>
                        <Path x:Name="CollapsedArrow" Stretch="Uniform" Stroke="#FF414345" HorizontalAlignment="Center" VerticalAlignment="Center" Width="5" Visibility="Collapsed" Data="F1 M 0,0 L 0,1 L .6,.5 L 0,0 Z"/>
                        <Path x:Name="ExpandedArrow" Fill="#FF414345" Stretch="Uniform" HorizontalAlignment="Center" VerticalAlignment="Center" Width="6" Data="F1 M 0,1 L 1,1 L 1,0 L 0,1 Z"/>
                      </Grid>
                    </ControlTemplate>
                  </dataPrimitives:DataGridFrozenGrid.Resources>
                  <dataPrimitives:DataGridFrozenGrid.ColumnDefinitions>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition Width="Auto"/>
                    <ColumnDefinition/>
                  </dataPrimitives:DataGridFrozenGrid.ColumnDefinitions>
                  <VisualStateManager.VisualStateGroups>
                    <VisualStateGroup x:Name="CurrentStates">
                      <VisualState x:Name="Regular"/>
                      <VisualState x:Name="Current">
                        <Storyboard>
                          <DoubleAnimation Duration="0" Storyboard.TargetName="FocusVisual" Storyboard.TargetProperty="Opacity" To="1"/>
                        </Storyboard>
                      </VisualState>
                    </VisualStateGroup>
                  </VisualStateManager.VisualStateGroups>
                  <dataPrimitives:DataGridFrozenGrid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition/>
                    <RowDefinition Height="Auto"/>
                  </dataPrimitives:DataGridFrozenGrid.RowDefinitions>
                  <Rectangle Fill="#FFFFFFFF" Height="1" Grid.Column="1" Grid.ColumnSpan="5"/>
                  <Rectangle x:Name="IndentSpacer" Grid.Column="1" Grid.Row="1"/>
                  <ToggleButton x:Name="ExpanderButton" Height="15" Margin="2,0,0,0" Width="15" Template="{StaticResource ToggleButtonTemplate}" Grid.Column="2" Grid.Row="1"/>
                  <StackPanel Margin="0,1,0,1" VerticalAlignment="Center" Grid.Column="3" Grid.Row="1" Orientation="Horizontal">
    
                    <TextBlock x:Name="PropertyNameElement" Margin="4,0,0,0" Visibility="{TemplateBinding PropertyNameVisibility}"/>
    
                    <TextBlock Margin="4,0,0,0" Text="{Binding Name}"/>
                    <TextBlock x:Name="ItemCountElement" Margin="4,0,0,0" Visibility="{TemplateBinding ItemCountVisibility}"/>
                  </StackPanel>
                  <Rectangle Fill="#FFD3D3D3" Height="1" Grid.Column="1" Grid.ColumnSpan="5" Grid.Row="2"/>
                  <Rectangle x:Name="FocusVisual" Stroke="#FF6DBDD1" StrokeThickness="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" IsHitTestVisible="false" Opacity="0" Grid.Column="1" Grid.ColumnSpan="4" Grid.RowSpan="3"/>
                  <dataPrimitives:DataGridRowHeader x:Name="RowHeader" Grid.RowSpan="3" dataPrimitives:DataGridFrozenGrid.IsFrozen="True"/>
                </dataPrimitives:DataGridFrozenGrid>
              </ControlTemplate>
            </Setter.Value>
          </Setter>
        </Style>
      </data:DataGrid.RowGroupHeaderStyles>
    </data:DataGrid>
    

    我在包含违规文本的TextBlock 前后添加了空行。您可以使用以下 XAML 将其完全关闭:

    <data:DataGrid>
       <data:DataGrid.RowGroupHeaderStyles>
         <Style TargetType="data:DataGridRowGroupHeader">
           <Setter Property="PropertyNameVisibility" Value="Collapsed"/>
         </Style>
      <data:DataGrid.RowGroupHeaderStyles>
    </data:DataGrid>
    

    如果您想修改文本,您将删除TextBlock 的名称并添加Text 属性:

    <TextBlock Margin="4,0,0,0" Visibility="{TemplateBinding PropertyNameVisibility}" Text="Client Name:"/>
    

    DataGridRowGroupHeader 将查找名为 PropertyNameElementTextBlock 并从代码中设置文本,为避免这种情况发生,您必须从模板中删除名称。

    【讨论】:

      【解决方案3】:

      我已经实现了 Martin Liversage 慷慨提供的模板(谢谢!),但我似乎无法控制组数据行的高度。调整矩形等的大小只会占用更多的空间,隐藏其他部分。行高似乎是由该行的容器控制的,不受模板的影响。 TIA 托比

      找到答案了!
      参考http://msdn.microsoft.com/en-us/library/cc278075(VS.95).aspx
      这定义了所有控件样式和模板,放大 DataGrid 并查看您会发现的默认模板:

      <data:DataGrid.RowGroupHeaderStyles>
      <Style TargetType="local:DataGridRowGroupHeader">
      <Setter Property="Cursor" Value="Arrow" />
      <Setter Property="IsTabStop" Value="False" />
      <Setter Property="Background" Value="#FFE4E8EA" />
      <Setter Property="Height" Value="20"/>
      <Setter Property="Template">
          <Setter.Value>
           <ControlTemplate TargetType="local:DataGridRowGroupHeader">
           ...snip...
           </ControlTemplate>
          </Setter.Value>
      </Setter>
      </Style>
      </data:DataGrid.RowGroupHeaderStyles>  
      

      设置 Height 属性就可以了。

      【讨论】:

      • 我花了大约 5 分钟试图弄清楚如何使用 Blend 获取默认模板,然后我打开了 Reflector 并从程序集的资源中提取了 generic.xaml。微软真的必须为此想出一个更好的解决方案,一堆愚蠢的...
      【解决方案4】:

      设置应用于您分组的属性的 Display 属性的 Name 属性:

      [System.ComponentModel.DataAnnotations.Display( Name = "My Property" )]
      public string MyProperty {get;set;}
      

      查看 Display 类,可能会认为 GroupName 是您设置的属性,但可惜不是。

      我知道用显示数据“混淆”模型并不总是每个人(包括我自己)都喜欢做事..但与以上述方式完成所需的工作量相比..我认为这次赢了。

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2010-12-24
        • 2011-03-16
        • 2011-01-02
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2011-01-15
        相关资源
        最近更新 更多