【问题标题】:Vertically aligning an expander button to the top of a DataGridRowHeader将展开器按钮垂直对齐到 DataGridRowHeader 的顶部
【发布时间】:2018-02-07 20:06:45
【问题描述】:

在 DataGrid 中,我在行标题中添加了一个 Expander,它在功能上运行良好,但是当它垂直居中展开时。

我希望它保留在最初点击它的标题顶部。

我在这里错过了什么?

<DataGrid Name="dgAudit" 
          CanUserReorderColumns="False"
          CanUserAddRows="False"
          CanUserDeleteRows="False"
          CanUserResizeColumns="False"
          CanUserResizeRows="False"
          CanUserSortColumns="False"
          IsReadOnly="True"
          ItemsSource="{Binding GEOM_ASSET_OC_LIST}"
          HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto"
          AutoGenerateColumns="False"
          HorizontalAlignment="Stretch"
          VerticalAlignment="Stretch"
          RowDetailsVisibilityMode="Collapsed"
          >
    <DataGrid.RowHeaderTemplate>
        <DataTemplate>
            <Expander Template="{StaticResource NewExpander}"
                      OverridesDefaultStyle="True"
                      Header=""
                      HorizontalAlignment="Right"
                      VerticalAlignment="Top"
                      Expanded="Expander_Expanded" Collapsed="Expander_Collapsed"
                      >
            </Expander>
        </DataTemplate>
    </DataGrid.RowHeaderTemplate>

    <DataGrid.Columns>...

这里是主要模板:

<ControlTemplate x:Key="NewExpander" TargetType="{x:Type Expander}">
    <DockPanel>
        <ToggleButton x:Name="ExpanderButton" 
                      DockPanel.Dock="Top"
                      Template="{StaticResource AnimatedExpanderButtonTemp}"
                      Content="{TemplateBinding Header}"
                      IsChecked="{Binding Path=IsExpanded, RelativeSource={RelativeSource TemplatedParent}}"
                      OverridesDefaultStyle="True"
                      Padding="0.5,0">
        </ToggleButton>
    </DockPanel>
</ControlTemplate>

这是动画的模板:

<ControlTemplate x:Key="AnimatedExpanderButtonTemp" TargetType="{x:Type ToggleButton}">
    <Border x:Name="ExpanderButtonBorder"
            Background="{TemplateBinding Background}"
            BorderBrush="{TemplateBinding BorderBrush}"
            BorderThickness="{TemplateBinding BorderThickness}"
            Padding="{TemplateBinding Padding}" >
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="Auto"/>
                <ColumnDefinition Width="*"/>
            </Grid.ColumnDefinitions>
            <Rectangle Fill="Transparent"
                       Grid.ColumnSpan="2"/>
            <Ellipse Name="Circle"
                     Grid.Column="0"
                     Stroke="DarkGray"
                     Fill="LightGray"
                     Width="15"
                     Height="15"
                     HorizontalAlignment="Center"
                     VerticalAlignment="Center" />
            <Path x:Name="Arrow"
                  Grid.Column="0"
                  Data="M 1,1.5 L 4.5,5 8,1.5"
                  Stroke="#FF666666"
                  StrokeThickness="2"
                  HorizontalAlignment="Center"
                  VerticalAlignment="Center"
                  RenderTransformOrigin="0.5,0.5" >
                <Path.RenderTransform>
                    <RotateTransform Angle="0"/>
                </Path.RenderTransform>
            </Path>
        </Grid>
    </Border>
    <ControlTemplate.Triggers>
        <Trigger Property="IsChecked"
                 Value="True">
            <Trigger.EnterActions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="Arrow"
                                         Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)"
                                         To="180"
                                         Duration="0:0:0.4"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.EnterActions>
            <Trigger.ExitActions>
                <BeginStoryboard>
                    <Storyboard>
                        <DoubleAnimation Storyboard.TargetName="Arrow"
                                         Storyboard.TargetProperty="(Path.RenderTransform).(RotateTransform.Angle)"
                                         To="0"
                                         Duration="0:0:0.4"/>
                    </Storyboard>
                </BeginStoryboard>
            </Trigger.ExitActions>
        </Trigger>

        <Trigger Property="IsMouseOver" Value="true">
            <Setter Property="Stroke" Value="#FF3C7FB1" TargetName="Circle"/>
            <Setter Property="Stroke" Value="#222" TargetName="Arrow"/>
        </Trigger>
        <Trigger Property="IsPressed" Value="true">
            <Setter Property="Stroke" Value="#FF526C7B" TargetName="Circle"/>
            <Setter Property="StrokeThickness"  Value="1.5" TargetName="Circle"/>
            <Setter Property="Stroke" Value="#FF003366" TargetName="Arrow"/>
        </Trigger>
    </ControlTemplate.Triggers>
</ControlTemplate>

这里是展开折叠事件:

private void Expander_Expanded(object sender, RoutedEventArgs e) 
{ 
    for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual) 
    if (vis is DataGridRow) 
    { 
        var row = (DataGridRow)vis; 
        row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; 
        break; 
    } 
} 

private void Expander_Collapsed(object sender, RoutedEventArgs e) 
{ 
    for (var vis = sender as Visual; vis != null; vis = VisualTreeHelper.GetParent(vis) as Visual) 
    if (vis is DataGridRow) 
    { 
        var row = (DataGridRow)vis; 
        row.DetailsVisibility = row.DetailsVisibility == Visibility.Visible ? Visibility.Collapsed : Visibility.Visible; 
        break; 
    } 
}

【问题讨论】:

  • “垂直居中”?这是什么意思?您的问题无法重现:stackoverflow.com/help/mcve
  • 这意味着当行展开以显示行详细信息时,行标题依次展开并且行标题中的展开器按钮下降,因为它的垂直对齐方式以某种方式设置为中心。我希望扩展器按钮保留在标题的顶部。
  • 您的扩展器中没有内容,因此您的问题仍然无法重现...请参考链接。
  • 扩展器的内容通过控件模板填充,它是可复制的
  • 不,NewExpander ControlTemplate 只包含一个 ToggleButton 但没有 ContentPresenter,而且您还没有发布事件处理程序的代码。

标签: wpf xaml expander datagridrowheader


【解决方案1】:

默认DataGridRowHeader 模板中的ContentPresenter 具有Center 的硬编码VericalAlignment。您需要修改模板才能解决此问题:

<DataGrid.Resources>
    <BooleanToVisibilityConverter x:Key="bool2VisibilityConverter"/>
    <Style x:Key="RowHeaderGripperStyle" TargetType="{x:Type Thumb}">
        <Setter Property="Height" Value="8"/>
        <Setter Property="Background" Value="Transparent"/>
        <Setter Property="Cursor" Value="SizeNS"/>
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Thumb}">
                    <Border Background="{TemplateBinding Background}" Padding="{TemplateBinding Padding}"/>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
    <Style TargetType="{x:Type DataGridRowHeader}"
                       xmlns:Themes="clr-namespace:Microsoft.Windows.Themes;assembly=PresentationFramework.Aero2">
        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type DataGridRowHeader}">
                    <Grid>
                        <Themes:DataGridHeaderBorder BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" IsPressed="{TemplateBinding IsPressed}" IsHovered="{TemplateBinding IsMouseOver}" IsSelected="{TemplateBinding IsRowSelected}" Orientation="Horizontal" Padding="{TemplateBinding Padding}" SeparatorBrush="{TemplateBinding SeparatorBrush}" SeparatorVisibility="{TemplateBinding SeparatorVisibility}">
                            <StackPanel Orientation="Horizontal">
                                <ContentPresenter RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="Stretch"/>
                                <Control SnapsToDevicePixels="false" Template="{Binding ValidationErrorTemplate, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}" Visibility="{Binding (Validation.HasError), Converter={StaticResource bool2VisibilityConverter}, RelativeSource={RelativeSource AncestorType={x:Type DataGridRow}}}"/>
                            </StackPanel>
                        </Themes:DataGridHeaderBorder>
                        <Thumb x:Name="PART_TopHeaderGripper" Style="{StaticResource RowHeaderGripperStyle}" VerticalAlignment="Top"/>
                        <Thumb x:Name="PART_BottomHeaderGripper" Style="{StaticResource RowHeaderGripperStyle}" VerticalAlignment="Bottom"/>
                    </Grid>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>
</DataGrid.Resources>

不要忘记添加对PresentationFramework.Aero2.dll 的引用。

【讨论】:

  • 也适用于 Windows 7 上的 PresentationFramework.Aero.dll(Aero2 不工作)。
猜你喜欢
  • 1970-01-01
  • 2015-10-18
  • 2017-08-25
  • 2020-06-27
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2023-03-12
  • 2010-11-06
相关资源
最近更新 更多