在 WPF 和 XAML 中,如何让行详细信息的列在跳过多个列后动态更改以在父行下对齐?

Posted

技术标签:

【中文标题】在 WPF 和 XAML 中,如何让行详细信息的列在跳过多个列后动态更改以在父行下对齐?【英文标题】:In WPF and XAML, how can I get the row detail's column to change dynamically to align under the parent row after skipping a number of columns? 【发布时间】:2016-08-02 07:09:04 【问题描述】:

我的模型显示如下:

我想要实现的是,不是让行详细信息按默认方式显示,而是希望它们与父网格列对齐显示。我希望详细信息网格跳过前 3 列(留空),然后将详细信息与父行的“街道名称”、“街道编号”、列对齐。

如果有人能指出我应该研究的属性来实现这一点,那就太好了。

更新: 我取得了一些进展,但仍然没有完全通过。我的行显示了我想要的方式,但是在调整列大小时它会中断。我没有发现任何与 Column width changed 或类似的事件相关来编写代码来调整宽度。它是如何在 WPF 中完成的?另外,有没有更好的方法来实现这一点?

xaml 代码为:

<Window x:Class="AligningDetailsView.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:local="clr-namespace:AligningDetailsView"
    mc:Ignorable="d"
    Title="MainWindow" Height="350" Width="525"
    DataContext="Binding RelativeSource=RelativeSource Self">
<Window.Resources>
    <CollectionViewSource x:Key="customerViewSource"
                          Source="Binding Customers"
                          d:DesignSource="d:DesignInstance x:Type local:Customer, CreateList=True" />
</Window.Resources>
<Grid>

    <DataGrid x:Name="customerDataGrid"
              ItemsSource="Binding Source=StaticResource customerViewSource"
              EnableRowVirtualization="True"
              AutoGenerateColumns="False" RowDetailsVisibilityMode="VisibleWhenSelected"
              Margin="0,27,0.4,-0.2">
        <DataGrid.Columns>
            <DataGridTextColumn x:Name="firstNameColumn"
                                Width="100"
                                Header="First Name"
                                Binding="Binding FirstName" />
            <DataGridTextColumn x:Name="lastNameColumn"
                                Width="100"
                                Header="Last Name"
                                Binding="Binding LastName" />
            <DataGridTextColumn x:Name="phoneColumn"
                                Width="100"
                                Header="Age"
                                Binding="Binding Age" />
            <DataGridTextColumn x:Name="colStreetNumber"
                                Width="100"
                                Header="StreetNumber" />
            <DataGridTextColumn x:Name="colStreetName"
                                Width="100"
                                Header="StreetNumber" />
            <DataGridTextColumn x:Name="colState"
                                Width="100"
                                Header="State" />
        </DataGrid.Columns>
        <DataGrid.RowDetailsTemplate>
            <DataTemplate>
                <DataGrid ItemsSource="Binding Addresses"
                          RowHeaderWidth="300"
                          HeadersVisibility="Row"
                          AutoGenerateColumns="False">

                    <DataGrid.Columns>
                        <DataGridTextColumn x:Name="detail1"
                                 Binding="Binding StreetNumber"            Width="100" />
                        <DataGridTextColumn x:Name="detail2"
                                            Width="100" Binding="Binding StreetName" />
                        <DataGridTextColumn x:Name="detail3"
                                            Width="100" Binding="Binding State" />
                    </DataGrid.Columns>
                </DataGrid>

            </DataTemplate>
        </DataGrid.RowDetailsTemplate>
    </DataGrid>
</Grid>

后面的代码是:

 public partial class MainWindow : Window

    public MainWindow()
    
        Customers = GetCustomers();
        InitializeComponent();
    

    private List<Customer> GetCustomers()
    
        return new List<Customer>()
        
            new Customer()
            
                FirstName = "James",
                LastName = "aka",
                Age = 22,
                Addresses = new List<Address>()
                
                    new Address()
                    
                        StreetName = "abdf st",
                        StreetNumber = 123,
                        State = "OH"
                    ,
                    new Address()
                    
                        StreetName = "skdjf abdf st",
                        StreetNumber = 12233,
                        State = "OH"
                    
                
            
        ;
    
    public List<Customer> Customers  get; set; 


public class Customer

    public string FirstName  get; set; 
    public string LastName  get; set; 
    public int Age  get; set; 
    public List<Address> Addresses  get; set; 


public class Address

    public int StreetNumber  get; set; 
    public string StreetName  get; set; 
    public string State  get; set; 

【问题讨论】:

【参考方案1】:

可以去掉行头,也就是子行左边的小间隙:

<DataGrid RowHeaderWidth="50" ... >

【讨论】:

我的意思是我希望详细信息行位于第一行的街道名称、街道编号等列标题下方,而不是让它们显示为自己的网格。 首先修改您的问题以使其更清晰,然后添加一些 Xaml 和代码以显示您已经完成的工作。 benPearce,我根据您提供的 RowHeaderWidth 信息取得了一些进展。我还用代码更新了我的问题。我正在考虑向 ColumnHeaderWidthChanged 之类的事件添加代码,但似乎没有这样的可用代码。您是否碰巧知道当用户更改父列宽时如何调整详细信息列宽?谢谢。

以上是关于在 WPF 和 XAML 中,如何让行详细信息的列在跳过多个列后动态更改以在父行下对齐?的主要内容,如果未能解决你的问题,请参考以下文章

如何隐藏 WPF DataGrid 中的列标题?

WPF中XAML的触发器的属性,事件 都有那些?以及如何寻找

wpf 如何在tabContrl页中显示一个xaml页

在TextBlock WPF / Xaml中展开/缩小符号

WPF高手么,怎样在XAML中动态加载Rectangle控件,要能运行的啊!

wpf 带参数的用户控件,如何在xaml中引入