130517Dev GridControl建立多行复杂表头(Banded View)时,统计列与对应列无法对齐的解决办法

使用Dev GridControl建立多行复杂表头时,TotalSummaryItem统计列始终无法与对应列对齐,也无法与对应列一起调整宽度。

最终通过Dev官方网站的技术支持那里得到了最终解决办法,公布如下,供大家参考。

具体的实现原理我也不太懂,总而言之,按照该方法,粘贴部分代码到自己的项目中,能够解决问题。

MainWindow.xaml代码:

  1 <Window x:Class="GridExample.MainWindow"
  2         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4         xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
  5         xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
  6         xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
  7         xmlns:dxb="http://schemas.devexpress.com/winfx/2008/xaml/bars"
  8         xmlns:dxght="http://schemas.devexpress.com/winfx/2008/xaml/grid/internal"
  9         xmlns:dxgext="http://schemas.devexpress.com/winfx/2008/xaml/grid"
 10         xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
 11         xmlns:local="clr-namespace:GridExample"
 12         Width="500" Height="370"
 13         >
 14 
 15 
 16     <dxg:GridControl x:Name="grid" ItemsSource="{Binding}" Margin="5">
 17         <dxg:GridControl.View>
 18             <dxg:TableView ShowTotalSummary="True" >
 19                 <i:Interaction.Behaviors>
 20                     <dxgext:BandedViewBehavior>
 21                         <dxgext:BandedViewBehavior.ColumnDefinitions>
 22                             <dxgext:ColumnDefinition Width="*"/>
 23                             <dxgext:ColumnDefinition Width="*"/>
 24                         </dxgext:BandedViewBehavior.ColumnDefinitions>
 25                         <dxgext:BandedViewBehavior.RowDefinitions>
 26                             <dxgext:RowDefinition Height="Auto"/>
 27                             <dxgext:RowDefinition Height="Auto"/>
 28                         </dxgext:BandedViewBehavior.RowDefinitions>
 29                         <dxgext:BandedViewBehavior.TemplatesContainer>
 30                             <dxgext:TemplatesContainer/>
 31                         </dxgext:BandedViewBehavior.TemplatesContainer>
 32                     </dxgext:BandedViewBehavior>
 33                 </i:Interaction.Behaviors>
 34                 <dxg:TableView.FooterTemplate>
 35                     <DataTemplate>
 36                         <dx:MeasurePixelSnapper>
 37                             <ContentControl HorizontalAlignment="Stretch" HorizontalContentAlignment="Stretch"
 38                                         dxg:GridControl.CurrentView="{Binding Path=(dxg:GridControl.CurrentView), RelativeSource={RelativeSource TemplatedParent}}">
 39                                 <Grid>
 40                                     <Grid.Resources>
 41                                         <!--<ControlTemplate x:Key="{dxgt:TableViewThemeKey ResourceKey=FixedNoneDropPanelTemplate}">
 42                                                     <dx:StackVisibleIndexPanel ArrangeAccordingToVisibleIndex="True" Orientation="Horizontal" />
 43                                                 </ControlTemplate>-->
 44                                         <DataTemplate x:Key="TotalSummaryContainerTemplate">
 45                                             <dxg:GridTotalSummary DataContext="{Binding Path=DataContext, RelativeSource={RelativeSource TemplatedParent}}"
 46                               dxg:GridColumn.VisibleIndex="{Binding Path=Column.(dxg:GridColumn.VisibleIndex)}"
 47                               dxb:BarManager.DXContextMenu="{Binding Path=Column.View.DataControlMenu}">
 48                                                 <dxg:GridViewHitInfoBase.HitTestAcceptor>
 49                                                     <dxght:TotalSummaryTableViewHitTestAcceptor />
 50                                                 </dxg:GridViewHitInfoBase.HitTestAcceptor>
 51                                             </dxg:GridTotalSummary>
 52                                         </DataTemplate>
 53                                         <dx:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" />
 54                                         <dx:BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverterInverted" Invert="True" />
 55                                     </Grid.Resources>
 56                                     <Grid.ColumnDefinitions>
 57                                         <ColumnDefinition Width="Auto"/>
 58                                         <ColumnDefinition Width="*"/>
 59                                         <ColumnDefinition Width="17"/>
 60                                     </Grid.ColumnDefinitions>
 61                                     <ContentControl x:Name="PART_Indicator"
 62                                 Width="{Binding Path=(dxg:GridControl.CurrentView).IndicatorWidth, RelativeSource={RelativeSource TemplatedParent}}"
 63                                 Visibility="{Binding Path=(dxg:GridControl.CurrentView).ShowIndicator, RelativeSource={RelativeSource TemplatedParent}, Converter={StaticResource BooleanToVisibilityConverter}}"/>
 64                                     <dxg:GridScrollablePart 
 65                                         DataContext="{Binding Path=(dxg:GridControl.CurrentView).HeadersData, RelativeSource={RelativeSource TemplatedParent}}" 
 66                                         ScrollingMargin="{Binding Path=View.ScrollingHeaderVirtualizationMargin}" 
 67                                         FitContentWidth="{Binding Path=View.FitColumnWidth}" 
 68                                         dxg:GridControl.CurrentView="{Binding Path=View}" Grid.Column="1" 
 69                                         >
 70                                         <dxg:GridScrollablePart.FixedNoneContent>
 71                                             <local:BandedTotalSummaryItemsControl View="{Binding View}"
 72                                                         ItemTemplate="{StaticResource TotalSummaryContainerTemplate}"
 73                             x:Name="footerItemsControl"
 74                             ItemsSource="{Binding Path=(dxg:GridControl.CurrentView).HeadersData.FixedNoneCellData, RelativeSource={RelativeSource TemplatedParent}}"
 75                             >
 76                                                 <local:BandedTotalSummaryItemsControl.ItemsPanel>
 77                                                     <ControlTemplate>
 78                                                         <Grid/>
 79                                                     </ControlTemplate>
 80                                                 </local:BandedTotalSummaryItemsControl.ItemsPanel>
 81                                             </local:BandedTotalSummaryItemsControl>
 82                                         </dxg:GridScrollablePart.FixedNoneContent>
 83                                     </dxg:GridScrollablePart>
 84                                 </Grid>
 85                             </ContentControl>
 86                         </dx:MeasurePixelSnapper>
 87                     </DataTemplate>
 88                 </dxg:TableView.FooterTemplate>
 89             </dxg:TableView>
 90         </dxg:GridControl.View>
 91         <dxg:GridControl.TotalSummary>
 92             <dxg:GridSummaryItem FieldName="First" SummaryType="Count"/>
 93         </dxg:GridControl.TotalSummary>
 94         <dxg:GridControl.Columns>
 95             <dxg:GridColumn FieldName="Common" dxgext:BandedViewBehavior.ColumnSpan="2" dxgext:BandedViewBehavior.IsBand="True"/>
 96             <dxg:GridColumn FieldName="First" dxgext:BandedViewBehavior.Row="1"/>
 97             <dxg:GridColumn FieldName="Second" dxgext:BandedViewBehavior.Row="1" dxgext:BandedViewBehavior.Column="1"/>
 98         </dxg:GridControl.Columns>
 99     </dxg:GridControl>
100 </Window>
View Code

MainWindow.xaml.cs代码:

 1 using System;
 2 using System.Windows;
 3 using DevExpress.Xpf.Grid;
 4 using System.Windows.Controls;
 5 using System.Windows.Data;
 6 
 7 
 8 namespace GridExample {
 9     public partial class MainWindow : Window {
10         public MainWindow() {
11             InitializeComponent();
12         }
13     }
14 
15     public class Data {
16         public string First { get; set; }
17         public string Second { get; set; }
18     }
19 
20     public class BandedTotalSummaryItemsControl : TotalSummaryItemsControl {
21         public static readonly DependencyProperty ViewProperty =
22       DependencyProperty.Register("View", typeof(DataViewBase), typeof(BandedTotalSummaryItemsControl), null);
23         public DataViewBase View {
24             get { return (DataViewBase)GetValue(ViewProperty); }
25             set { SetValue(ViewProperty, value); }
26         }
27 
28         public BandedViewBehavior BandBehavior { get { return BandedViewBehavior.GetBandBehaviour((TableView)View); } }
29         Grid LayoutPanel { get { return (Grid)Panel; } }
30 
31         public BandedTotalSummaryItemsControl() {
32             Loaded += OnLoaded;
33         }
34 
35         protected override FrameworkElement CreateChild(object item) {
36             FrameworkElement res = base.CreateChild(item);
37             GridColumnData cellData = (GridColumnData)item;
38             ColumnBase gridColumn = cellData.Column;
39             int row = BandedViewBehavior.GetRow(gridColumn);
40             int column = BandedViewBehavior.GetColumn(gridColumn) + 1;
41             int rowSpan = BandedViewBehavior.GetRowSpan(gridColumn);
42             int columnSpan = BandedViewBehavior.GetColumnSpan(gridColumn);
43             Grid.SetRow(res, row);
44             Grid.SetColumn(res, column);
45             Grid.SetRowSpan(res, rowSpan);
46             Grid.SetColumnSpan(res, columnSpan);
47             if (BandedViewBehavior.GetIsBand(gridColumn)) res.Visibility = Visibility.Collapsed;
48             else res.Visibility = Visibility.Visible;
49             return res;
50         }
51         protected override void ValidateVisualTree() {
52             PreparePanel();
53             base.ValidateVisualTree();
54         }
55         void OnLoaded(object sender, RoutedEventArgs e) {
56             ClearPanel();
57         }
58         void ClearPanel() {
59             if (View == null || LayoutPanel == null) return;
60             InvalidateMeasure();
61             LayoutPanel.ColumnDefinitions.Clear();
62             LayoutPanel.RowDefinitions.Clear();
63         }
64         void PreparePanel() {
65             if (View == null || LayoutPanel == null) return;
66             if (LayoutPanel.ColumnDefinitions.Count != 0 || LayoutPanel.RowDefinitions.Count != 0) return;
67             CreateCorrectingColumn();
68             foreach (DevExpress.Xpf.Grid.ColumnDefinition columnDefinition in BandBehavior.ColumnDefinitions)
69                 LayoutPanel.ColumnDefinitions.Add(columnDefinition.CreateGridColumnDefinition());
70             foreach (DevExpress.Xpf.Grid.RowDefinition rowDefinition in BandBehavior.RowDefinitions)
71                 LayoutPanel.RowDefinitions.Add(rowDefinition.CreateGridRowDefinition());
72         }
73         void CreateCorrectingColumn() {
74             System.Windows.Controls.ColumnDefinition res = new System.Windows.Controls.ColumnDefinition();
75             Binding b = new Binding("GroupCount");
76             b.Source = ((GridControl)View.DataControl);
77             b.Converter = new GridLengthValueConverter();
78             b.ConverterParameter = ((TableView)View).LeftGroupAreaIndent;
79             BindingOperations.SetBinding(res, System.Windows.Controls.ColumnDefinition.WidthProperty, b);
80             LayoutPanel.ColumnDefinitions.Insert(0, res);
81 
82             Binding b1 = new Binding("Level");
83             b1.Source = DataContext;
84             b1.Converter = new ValueConverter();
85             b1.ConverterParameter = ((TableView)View).LeftGroupAreaIndent;
86             BindingOperations.SetBinding(this, CellLayoutControl.MarginProperty, b1);
87         }
88         class ValueConverter : IValueConverter {
89             public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
90                 double res = (int)value * (double)parameter;
91                 return new Thickness() { Left = -res };
92             }
93             public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) {
94                 throw new NotImplementedException();
95             }
96         }
97     }
98 }
View Code

类BandedTotalSummaryItemsControl 是重点,必须粘贴;xaml文件中<dxg:TableView.FooterTemplate>... ...</dxg:TableView.FooterTemplate>是重点,必须粘贴。

最终实现效果很好,和WinForm中的效果是一样滴。

最后感谢Dev的工程师。

原文地址:https://www.cnblogs.com/ljyuma/p/3083573.html