วิธีจัดกลุ่มส่วนหัวของคอลัมน์ DataGrid ใน WPF (2023)

ฉันสามารถเสนอวิธีแก้ไขปัญหาการจัดกลุ่มคอลัมน์ได้สามวิธี

โดยใช้การจัดกลุ่มแบบเดิมผ่านทางICollectionViewของแหล่งรวบรวม กลุ่มนี้เป็นแนวตั้ง หมายความว่าใช้คอลัมน์เดียวกัน

สร้างแหล่งข้อมูลที่ซ้อนกัน แนวคิดคือแต่ละคอลัมน์จะเชื่อมโยงกับชุดข้อมูลแต่ละชุดที่แสดงโดย aDataGridที่เพิ่มลงในคอลัมน์DataGridTemplateColumn. มันคือDataGridสำหรับแต่ละกลุ่มคอลัมน์ ข้อเสียของโซลูชันนี้คือข้อ จำกัด สำหรับโครงสร้างข้อมูลนั้นเข้มงวดมาก ไม่รองรับ DataTable และไม่มีการสร้างคอลัมน์อัตโนมัติ ความพยายามเพิ่มขึ้นหากอนุญาตให้เรียงลำดับคอลัมน์หรือเรียงลำดับใหม่ได้ แต่สำหรับการแสดงตารางที่จัดกลุ่มอย่างง่าย วิธีนี้ใช้ได้ดีพอ

ตัวอย่างการใช้งาน

วิธีจัดกลุ่มส่วนหัวของคอลัมน์ DataGrid ใน WPF (1)

(Video) WPF Controls | 27-Datagrid Custom Datagrid | Part 6 Styling

หน้าต่างหลัก.xaml

<หน้าต่าง>                               DataTemplate>        

ขอแนะนำให้ปิดการแก้ไขตารางผ่านทางDataGrid. เพื่อทำให้รูปลักษณ์สวยงามเช่นการเน้นชื่อกลุ่มหรือลบล้างDataGridRowเทมเพลตเพื่อเพิ่มการเน้นแถวสำหรับกริดที่ไม่ได้โฟกัสนั้นค่อนข้างง่าย

ตัวอย่างการใช้งาน

โครงสร้างข้อมูลสำหรับตารางที่ซ้อนกัน:

DataGridRowItem.cs
องค์ประกอบราก รายการแถวเดียวสำหรับระดับบนสุดDataGrid
ที่จะแสดงส่วนหัวของกลุ่มคอลัมน์ กลุ่มคอลัมน์สำหรับแต่ละกลุ่มDataGridColumnItem.

(Video) Adding a Data Grid in WPF

DataGridRowItem ระดับสาธารณะ { รายการสาธารณะ < DataGridColumnItem > คอลัมน์ { รับ; ชุด; }}

DataGridColumnItem.cs
แต่ละDataGridColumnItemจะสร้างกลุ่มคอลัมน์

DataGridColumnItem คลาสสาธารณะ { GroupHeader สตริงสาธารณะ { รับ; ชุด; } รายการสาธารณะ <นัดหมาย> TableData { รับ; ชุด; }}

การนัดหมาย.cs
แบบจำลองข้อมูลจริงที่แสดงในกลุ่มDataGrid.

การนัดหมายระดับสาธารณะ { สาธารณะ DateTime เริ่ม { รับ; ชุด; } สิ้นสุด DateTime สาธารณะ { รับ; ชุด; }}

ViewModel.cs

คลาสสาธารณะ TestViewModel: ViewModel{ รายการสาธารณะ  แถว { รับ; } ViewModel สาธารณะ () { this.GroupingRow = รายการใหม่  { // แถวเดียวสำหรับการจัดกลุ่ม DataGrid ระดับบนสุดใหม่ DataGridRowItem () { คอลัมน์ = รายการใหม่  () { // กลุ่มคอลัมน์แรกใหม่ DataGridColumnItem ( ) { GroupHeader = "กลุ่ม 1", TableData = รายการใหม่<การนัดหมาย> { การนัดหมายใหม่ () { เริ่ม = DateTime.Now.AddDays (1), สิ้นสุด = DateTime.Now.AddDays (2) } การนัดหมายใหม่ () { Start = DateTime.Now.AddDays(5), End = DateTime.Now.AddDays(6) } } }, // กลุ่มคอลัมน์ที่สอง new DataGridColumnItem() { GroupHeader = "Group 2", TableData = new List { การนัดหมายใหม่ () { เริ่ม = DateTime.Now.AddDays (3), สิ้นสุด = DateTime.Now.AddDays (4) }, การนัดหมายใหม่ () { เริ่ม = DateTime.Now.AddDays (7), สิ้นสุด = DateTime.Now เพิ่มวัน (8) } } } } } }; }}

DataGridHelper.cs
ลักษณะการทำงานที่แนบมาซึ่งช่วยในการซิงโครไนซ์แถวที่เลือกระหว่างหลาย ๆDataGridตัวอย่าง. ลักษณะการทำงานเดิมเขียนขึ้นสำหรับปัญหาที่แตกต่างกัน แต่สามารถใช้ซ้ำในสถานการณ์นี้ได้เช่นกัน อนุญาตให้สร้างกลุ่มการซิงโครไนซ์ของDataGridองค์ประกอบ

(Video) WPF Controls | 27-Datagrid | Part 3 | Datagrid in WPF | WPF Datagrid

DataGridHelper คลาสสาธารณะ: DependencyObject{ วัตถุคงที่สาธารณะ GetSynchronizeGroupKey (DependencyObject AttachElement) => (วัตถุ)attachedElement.GetValue (SynchronizeGroupKeyProperty); โมฆะคงที่สาธารณะ SetSynchronizeGroupKey (DependencyObject AttachElement, ค่าวัตถุ) => AttachElement.SetValue (SynchronizeGroupKeyProperty, ค่า); แบบสาธารณะแบบอ่านอย่างเดียว บูลคงที่สาธารณะ GetIsSynchronizeSelectedRowEnabled (DependencyObject AttachElement) => (บูล)attachedElement.GetValue (IsSynchronizeSelectedRowEnabledProperty); โมฆะสาธารณะคงที่ SetIsSynchronizeSelectedRowEnabled (DependencyObject AttachElement, ค่าบูล) =>ที่แนบมาElement.SetValue (IsSynchronizeSelectedRowEnabledProperty, ค่า); แบบคงที่สาธารณะแบบอ่านอย่างเดียว DependencyProperty IsSynchronizeSelectedRowEnabledProperty = DependencyProperty.RegisterAttached ( "IsSynchronizeSelectedRowEnabled", typeof (bool), typeof (DataGridHelper), New PropertyMetadata (default (bool), OnIsSynchronizeSelectedRowEnabledChanged)); พจนานุกรมคงที่ส่วนตัว <วัตถุ IList >> DataGridTable { รับ; } = พจนานุกรมใหม่ <วัตถุ IList >>(); โมฆะคงที่ส่วนตัว OnIsSynchronizeSelectedRowEnabledChanged (DependencyObject AttachingElement, DependencyPropertyChangedEventArgs e) { ถ้า (attachingElement ไม่ใช่ DataGrid dataGrid) { โยน ArgumentException ใหม่ ($"องค์ประกอบที่แนบต้องเป็นประเภท {typeof(DataGrid)}.", ชื่อของ (attachingElement)); } ถ้า ((บูล) e.NewValue) { RegisterDataGridForSelectedItemSynchronization (dataGrid); } อื่น { UnregisterDataGridForSelectedItemSynchronization (dataGrid); } } โมฆะส่วนตัวคงที่ RegisterDataGridForSelectedItemSynchronization (DataGrid dataGrid) => WeakEventManager .AddHandler (dataGrid, nameof (DataGrid.SelectionChanged), SynchronizeSelectedItem_OnSelectionChanged); โมฆะคงที่ส่วนตัว UnregisterDataGridForSelectedItemSynchronization (DataGrid dataGrid) => WeakEventManager .RemoveHandler (dataGrid, nameof (DataGrid.SelectionChanged), SynchronizeSelectedItem_OnSelectionChanged); โมฆะคงที่ส่วนตัว OnSynchronizeGroupKeyChanged (DependencyObject AttachingElement, DependencyPropertyChangedEventArgs e) { ถ้า (attachingElement ไม่ใช่ DataGrid dataGrid) { โยน ArgumentException ใหม่ ($"องค์ประกอบที่แนบต้องเป็นประเภท {typeof(DataGrid)}.", nameof (attachingElement)); } ถ้า (e.NewValue == null) { โยน ArgumentNullException ใหม่ ($"{null} ไม่ใช่ค่าที่ถูกต้องสำหรับคุณสมบัติที่แนบมา {nameof(SynchronizeGroupKeyProperty)}.", nameof(e.NewValue)); } if (!DataGridTable.TryGetValue(e.NewValue, out IList>? dataGridGroup)) { dataGridGroup = รายการใหม่>(); DataGridTable.Add (e.NewValue, dataGridGroup); } dataGridGroup.Add (ใหม่ WeakReference(dataGrid)); } โมฆะส่วนตัวคงที่ SynchronizeSelectedItem_OnSelectionChanged (ผู้ส่งวัตถุ SelectionChangedEventArgs e) { var synchronizationSourceDataGrid = ผู้ส่งเป็น DataGrid; การซิงโครไนซ์ varSourceDataGridGroupKey = GetSynchronizeGroupKey (การซิงโครไนซ์SourceDataGrid); ถ้า (! DataGridTable.TryGetValue (การซิงโครไนซ์SourceDataGridGroupKey, ออก IList> dataGridGroup)) { กลับ; } var SelectedIndices = การซิงโครไนซ์SourceDataGrid.SelectedItems .Cast() .Select(synchronizationSourceDataGrid.Items.IndexOf) .ToList(); foreach (WeakReference dataGridReference ใน dataGridGroup) { if (!dataGridReference.TryGetTarget(out DataGrid dataGrid) || dataGrid == synchronizationSourceDataGrid || dataGrid.Items.Count == 0) { ดำเนินการต่อ; } UnregisterDataGridForSelectedItemSynchronization (dataGrid); dataGrid.SelectedItems.Clear(); foreach (int SelectedItemIndex ใน SelectedIndices) { var SelectedItem = dataGrid.Items [selectedItemIndex]; dataGrid.SelectedItems.Add (รายการที่เลือก); } RegisterDataGridForSelectedItemSynchronization (dataGrid); } }}

โซลูชันที่มีประสิทธิภาพมากกว่าคือการใช้การควบคุมแบบกำหนดเอง ด้วยวิธีนี้ เช่น การจัดลำดับใหม่/ปรับขนาดคอลัมน์ เพิ่ม/ลบแถว และการปรับแต่งจะสะดวกมาก
การควบคุมแบบกำหนดเองการจัดกลุ่ม DataGridโดยทั่วไปจะห่อแบบกำหนดเองDataGridเป็นตาราง.
โซลูชันนี้รองรับการสร้างอัตโนมัติและการกำหนดคอลัมน์ที่ชัดเจน กลุ่มคอลัมน์และแต่ละคอลัมน์สามารถปรับขนาดได้
เดอะDataGridซึ่งจัดโดยการจัดกลุ่ม DataGridสามารถใช้ได้โดยไม่มีข้อจำกัดใดๆ เลย์เอาต์นั้นสะอาดและคำจำกัดความของกลุ่มคอลัมน์ (โดยใช้ไฟล์คำจำกัดความของกลุ่มตามสไตล์คำจำกัดความของ Grid) ค่อนข้างสะดวก
ในการปรับแต่งส่วนหัวของกลุ่ม ให้กำหนด aสไตล์ที่กำหนดเป้าหมายการจัดกลุ่ม DataGridHeader(ซึ่งก็คือกคอนเทนท์คอนโทรล).
เดอะการจัดกลุ่ม DataGridเป็นตัวควบคุมที่มีอยู่จากห้องสมุดของฉัน ฉันลบโค้ดบางส่วน ซึ่งส่วนใหญ่เป็นคุณสมบัติการปรับแต่ง เช่น เทมเพลต ออกจากแหล่งที่มา เพื่อให้โพสต์มีความกระชับมากที่สุด

ตัวอย่างการใช้งาน

วิธีจัดกลุ่มส่วนหัวของคอลัมน์ DataGrid ใน WPF (2)

         

รหัสแหล่งที่มา

GroupingDataGrid.cs

[ContentProperty(nameof(GroupingDataGrid.DataGrid))]GroupDataGrid คลาสสาธารณะ: ควบคุม{ ​​GroupDefinitionCollection GroupDefinitions สาธารณะ { รับ => (GroupDefinitionCollection)GetValue(GroupDefinitionsProperty); set => SetValue(GroupDefinitionsProperty, ค่า); } คงที่สาธารณะแบบอ่านอย่างเดียว DependencyProperty GroupDefinitionsProperty = DependencyProperty.Register ( "GroupDefinitions", typeof (GroupDefinitionCollection), typeof (GroupingDataGrid), PropertyMetadata ใหม่ (ค่าเริ่มต้น)); DataGrid DataGrid สาธารณะ { รับ { คืน (DataGrid) GetValue (DataGridProperty); } ชุด { SetValue (DataGridProperty, ค่า); } } แบบคงที่สาธารณะแบบอ่านอย่างเดียว DependencyProperty DataGridProperty = DependencyProperty.Register ( "DataGrid", typeof (DataGrid), typeof (GroupingDataGrid), PropertyMetadata ใหม่ (ค่าเริ่มต้น (DataGrid), OnDataGridChanged)); GroupingDataGrid แบบคงที่ () { DefaultStyleKeyProperty.OverrideMetadata (typeof (GroupingDataGrid), FrameworkPropertyMetadata ใหม่ (typeof (GroupingDataGrid))); } โมฆะส่วนตัวคงที่ OnDataGridChanged (DependencyObject d, DependencyPropertyChangedEventArgs e) => (d เป็น GroupingDataGrid).OnDataGridChanged (e.OldValue เป็น DataGrid, e.NewValue เป็น DataGrid); บูลส่วนตัว IsDataGridLayoutDirty { รับ; ชุด; } ส่วนตัว Grid GroupHost { รับ; } พจนานุกรมส่วนตัว  ThumbToGroupingDataGridHeaderTable { รับ; } พจนานุกรมส่วนตัว  GroupDefinitionToGroupingDataGridHeaderTable { รับ; } GroupingDataGrid สาธารณะ () { this.GroupDefinitions = GroupDefinitionCollection ใหม่ (); this.ThumbToGroupingDataGridHeaderTable = พจนานุกรมใหม่ (); this.GroupDefinitionToGroupingDataGridHeaderTable = พจนานุกรมใหม่ (); this.GroupHost = ตารางใหม่ (); this.GroupHost.RowDefinitions.Add (ใหม่ RowDefinition () { ความสูง = GridLength.Auto }); this.GroupHost.RowDefinitions.Add (ใหม่ RowDefinition () { ความสูง = GridLength.Auto }); } การแทนที่สาธารณะเป็นโมฆะ OnApplyTemplate () { base.OnApplyTemplate (); var contentHost = GetTemplateChild("PART_DataGridHost") เป็น ContentPresenter ถ้า (contentHost != null) { contentHost.Content = this.GroupHost; } } โมฆะเสมือนที่ได้รับการป้องกัน OnDataGridChanged (DataGrid oldDataGrid, DataGrid newDataGrid) { ถ้า (oldDataGrid != null) { this.GroupHost.Children.Remove (oldDataGrid); oldDataGrid.ColumnDisplayIndexChanged -= OnColumnOrderChanged; oldDataGrid.AutoGeneratedColumns -= OnDataGridAutoGeneratedColumns; } ถ้า (newDataGrid == null) { กลับ; } this.IsDataGridLayoutDirty = จริง; this.GroupHost.Child.Add (this.DataGrid); newDataGrid.ColumnDisplayIndexChanged += OnColumnOrderChanged; ถ้า (newDataGrid.AutoGenerateColumns && !newDataGrid.IsLoaded) { newDataGrid.AutoGeneratedColumns += OnDataGridAutoGeneratedColumns; } อื่น { CreateVisualTree(); } } โมฆะส่วนตัว OnColumnOrderChanged (วัตถุ? ผู้ส่ง, DataGridColumnEventArgs e) => CreateVisualTree (); โมฆะส่วนตัว OnDataGridAutoGeneratedColumns (ผู้ส่งวัตถุ, EventArgs e) => CreateVisualTree (); โมฆะส่วนตัว CreateVisualTree () { CreateGroups (); ถ้า (this.IsDataGridLayoutDirty) { LayoutDataGrid (); } } โมฆะส่วนตัว CreateGroups () { this.ThumbToGroupingDataGridHeaderTable.Clear (); this.GroupDefinitionToGroupingDataGridHeaderTable.Clear(); ClearGroupHost(); AddRowHeaderColumnGroup(); รายการ sortedColumns = this.DataGrid.Columns .OrderBy(column => column.DisplayIndex) .ToList(); int ungroupedColumnCount = sortedColumns.Count - this.GroupDefinitions.Sum(definition => definition.ColumnSpan); บูล hasUngroupedColumns = ungroupedColumnCount > 0; สำหรับ (int groupIndex = 0; groupIndex < this.GroupDefinitions.Count; groupIndex ++) { กลุ่ม GroupDefinition = this.GroupDefinitions [groupIndex]; int groupHeaderColumnIndex = groupIndex + 1; AddGridColumn(); AddGroupHeader(group, groupHeaderColumnIndex, sortedColumns); ถ้า (groupHeaderColumnIndex > 1) { GroupDefinition ก่อนหน้ากลุ่ม = this.GroupDefinitions [groupIndex - 1]; AddColumnGrippers (กลุ่มก่อนหน้า, groupHeaderColumnIndex - 1); } } ถ้า (hasUngroupedColumns) { AddGroupForRemainingColumns(); } } โมฆะส่วนตัว AddGroupForRemainingColumns () { AddGridColumn (เท็จ); AddGroupHeader (null, this.GroupHost.ColumnDefinitions.Count - 1, รายการใหม่ ()); ถ้า (this.GroupDefinitions.Any ()) { GroupDefinition PreviousGroup = this.GroupDefinitions.Last (); AddColumnGrippers (กลุ่มก่อนหน้า, this.GroupDefinitions.Count); } } โมฆะส่วนตัว CreateColumnGroupHeaderBinding (IList  sortedColumns, GroupingDataGridHeader groupHeaderHost) { GroupDefinition group = groupHeaderHost.GroupDefinition; var groupHeaderWidthMultiBinding = MultiBinding ใหม่ { โหมด = BindingMode.TwoWay, Converter = ใหม่ DataGridColumnRangeWidthToGroupHeaderWidthConverter (sortedColumns), ConverterParameter = group }; สำหรับ (int columnIndex = group.Column; columnIndex < group.Column + group.ColumnSpan; columnIndex ++) { คอลัมน์ DataGridColumn = sortedColumns[columnIndex]; var widthBinding = การผูกใหม่ (nameof (DataGridColumn.Width)) { โหมด = BindingMode.TwoWay, แหล่งที่มา = คอลัมน์ }; groupHeaderWidthMultiBinding.Bindings.Add (widthBinding); } groupHeaderHost.SetBinding (ความกว้างคุณสมบัติ, groupHeaderWidthMultiBinding); } ส่วนตัว GroupingDataGridHeader AddGroupHeader (กลุ่ม GroupDefinition, int groupHeaderColumnIndex, รายการ  sortedColumns) { var groupHeaderHost = ใหม่ GroupingDataGridHeader (กลุ่ม); Grid.SetColumn(groupHeaderHost, groupHeaderColumnIndex); Grid.SetRow(groupHeaderHost, 0); this.GroupHost.Child.Add (groupHeaderHost); ถ้า (กลุ่ม != null) { this.GroupDefinitionToGroupingDataGridHeaderTable.Add (กลุ่ม, groupHeaderHost); ถ้า (sortedColumns.Any ()) { CreateColumnGroupHeaderBinding (sortedColumns, groupHeaderHost); } } กลับ groupHeaderHost; } โมฆะส่วนตัว AddGridColumn (บูล isAutoWidth = จริง) { var gridColumnWidth = isAutoWidth ? GridLength.Auto : ใหม่ GridLength(1, GridUnitType.Star); var groupHeaderHostColumnDefinition = ใหม่ ColumnDefinition () { ความกว้าง = gridColumnWidth }; this.GroupHost.ColumnDefinitions.Add (groupHeaderHostColumnDefinition); } โมฆะส่วนตัว AddColumnGrippers (GroupDefinition groupDefinition, int groupHeaderColumnIndex) { GroupingDataGridHeader groupHeaderHost = this.GroupDefinitionToGroupingDataGridHeaderTable [groupDefinition]; AddColumnGripper (groupHeaderColumnIndex, groupHeaderHost, จริง); AddColumnGripper (groupHeaderColumnIndex + 1, groupHeaderHost); } โมฆะส่วนตัว AddColumnGripper (int columnIndex, GroupingDataGridHeader groupHeader, bool isLeftColumnGripper = false) { var columnGripper = new Thumb() { HorizontalAlignment = isLeftColumnGripper ? HorizontalAlignment.Right : HorizontalAlignment.Left, }; columnGripper.DragDelta += OnGroupHeaderResizing; this.ThumbToGroupingDataGridHeaderTable.Add (columnGripper, groupHeader); Grid.SetColumn(columnGripper, columnIndex); Grid.SetRow(columnGripper, 0); this.GroupHost.Child.Add (คอลัมน์กริปเปอร์); } โมฆะส่วนตัว LayoutDataGrid () { Grid.SetColumnSpan (this.DataGrid, this.GroupHost.ColumnDefinitions.Count); Grid.SetRow(this.DataGrid, 1); this.IsDataGridLayoutDirty = เท็จ; } โมฆะส่วนตัว AddRowHeaderColumnGroup () { AddGridColumn (); GroupingDataGridHeader rowHeaderGroupHost = AddGroupHeader(null, 0, new List()); var rowHeaderWidthBinding = การผูกใหม่ (ชื่อ (DataGrid.RowHeaderActualWidth)) { ที่มา = this.DataGrid }; rowHeaderGroupHost.SetBinding (WidthProperty, rowHeaderWidthBinding); } โมฆะส่วนตัว ClearGroupHost () { สำหรับ (int childIndex = this.GroupHost.Children.Count - 1; childIndex >= 0; childIndex--) { var child = this.GroupHost.Children[childIndex]; ถ้า (ลูก != this.DataGrid) { this.GroupHost.Children.Remove (ลูก); } } } โมฆะส่วนตัว OnGroupHeaderResizing (ผู้ส่งวัตถุ, DragDeltaEventArgs e) { var thumb = ผู้ส่งเป็น Thumb; ถ้า (นี้ ThumbToGroupingDataGridHeaderTable.TryGetValue (นิ้วหัวแม่มือ, ออก GroupingDataGridHeader groupingDataGridHeader)) { groupingDataGridHeader.Width += e.HorizontalChange; } }}

GroupingDataGridHeader.cs

(Video) WPF Grid and TreeList: Dynamic Column Resizing

GroupingDataGridHeader คลาสสาธารณะ: ContentControl { สาธารณะ GroupDefinition GroupDefinition { รับ; } GroupingDataGridHeader สาธารณะ () : สิ่งนี้ (GroupDefinition ใหม่ ()) { } GroupingDataGridHeader สาธารณะ (GroupDefinition groupDefinition) { this.GroupDefinition = groupDefinition; this.Content = this.GroupDefinition?.Header ?? string.Empty; } GroupingDataGridHeader แบบคงที่ () { DefaultStyleKeyProperty.OverrideMetadata (typeof (GroupingDataGridHeader), FrameworkPropertyMetadata ใหม่ (typeof (GroupingDataGridHeader))); }}

GroupDefinition.cs

GroupDefinition คลาสสาธารณะ: FrameworkContentElement { คอลัมน์ int สาธารณะ { รับ => (int) GetValue (ColumnProperty); set => SetValue(ColumnProperty, ค่า); } คงที่สาธารณะแบบอ่านอย่างเดียว DependencyProperty ColumnProperty = DependencyProperty.Register ( "คอลัมน์", typeof (int), typeof (GroupDefinition), PropertyMetadata ใหม่ (ค่าเริ่มต้น)); int สาธารณะ ColumnSpan { รับ => (int) GetValue (ColumnSpanProperty); set => SetValue(ColumnSpanProperty, ค่า); } คงที่สาธารณะแบบอ่านอย่างเดียว DependencyProperty ColumnSpanProperty = DependencyProperty.Register ( "ColumnSpan", typeof (int), typeof (GroupDefinition), PropertyMetadata ใหม่ (ค่าเริ่มต้น)); ส่วนหัวของวัตถุสาธารณะ { รับ => (วัตถุ) GetValue (HeaderProperty); set => SetValue(HeaderProperty, ค่า); } คงที่สาธารณะแบบอ่านอย่างเดียว DependencyProperty HeaderProperty = DependencyProperty.Register ( "Header", typeof (object), typeof (GroupDefinition), New PropertyMetadata (default));}

GroupDefinitionCollection.cs

GroupDefinitionCollection คลาสสาธารณะ : Collection{ }

DataGridColumnRangeWidthToGroupHeaderWidthConverter.cs

DataGridColumnRangeWidthToGroupHeaderWidthConverter คลาสสาธารณะ: IMultiValueConverter { ส่วนตัว IList  DataGridColumns { รับ; } DataGridColumnRangeWidthToGroupHeaderWidthConverter สาธารณะ (IList  dataGridColumns) { this.DataGridColumns = dataGridColumns; } วัตถุสาธารณะ แปลง (ค่าวัตถุ [], ประเภท targetType, พารามิเตอร์วัตถุ, วัฒนธรรม CultureInfo) => ค่า Cast  (). ผลรวม (gridLength => gridLength.DisplayValue); วัตถุสาธารณะ [] ConvertBack (ค่าวัตถุ, ประเภท [] targetTypes, พารามิเตอร์วัตถุ, วัฒนธรรม CultureInfo) { var groupDefinition = (GroupDefinition) พารามิเตอร์; กระแสคู่ GroupedColumnsWidth = this.DataGridColumns .Skip(groupDefinition.Column) .Take(groupDefinition.ColumnSpan) .Select(column => column.Width.DisplayValue) .Sum(); ผลลัพธ์ var = วัตถุใหม่ [groupDefinition.ColumnSpan]; Array.Fill(ผลลัพธ์ Binding.DoNothing); DataGridColumn lastGroupColumn = this.DataGridColumns[groupDefinition.Column + groupDefinition.ColumnSpan - 1]; var newColumnWidth = DataGridLength ใหม่ (lastGroupColumn.Width.DisplayValue + ค่า (สองเท่า) - currentGroupedColumnsWidth, DataGridLengthUnitType.Pixel); ผลลัพธ์[result.Length - 1] = newColumnWidth; ส่งคืนผลลัพธ์ }}

ทั่วไป.xaml

(Video) Grid Shared Size Scoping/Grouping - EASY WPF (.NET 5)

 <สไตล์ TargetType="local:GroupingDataGrid">  <สไตล์ TargetType="Thumb">               < ControlTemplate TargetType="local:GroupingDataGrid">       

Videos

1. Datagrid
(Moreix Inc)
2. DevExpress WPF Data Grid: Banded Layout
(DevExpress)
3. Perform Grouping in Xamarin Forms DataGrid
(Syncfusion, Inc)
4. VB.NET Datagridview, ComboBox Calculate Price โปรแกรมคำนวณราคาสินค้า
(Aj. Nop)
5. Advanced DataGridview with excel-like auto filter in C# | C# Advanced DatagridView filter [ CSHARP ]
(Programming Guru)
6. c# tutorial for beginners: Send data from datagridview to crystalreport without database in C#
(Programming for Everybody)

References

Top Articles
Latest Posts
Article information

Author: Gov. Deandrea McKenzie

Last Updated: 10/08/2023

Views: 5397

Rating: 4.6 / 5 (46 voted)

Reviews: 85% of readers found this page helpful

Author information

Name: Gov. Deandrea McKenzie

Birthday: 2001-01-17

Address: Suite 769 2454 Marsha Coves, Debbieton, MS 95002

Phone: +813077629322

Job: Real-Estate Executive

Hobby: Archery, Metal detecting, Kitesurfing, Genealogy, Kitesurfing, Calligraphy, Roller skating

Introduction: My name is Gov. Deandrea McKenzie, I am a spotless, clean, glamorous, sparkling, adventurous, nice, brainy person who loves writing and wants to share my knowledge and understanding with you.