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>
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 }
类BandedTotalSummaryItemsControl 是重点,必须粘贴;xaml文件中<dxg:TableView.FooterTemplate>... ...</dxg:TableView.FooterTemplate>是重点,必须粘贴。
最终实现效果很好,和WinForm中的效果是一样滴。
最后感谢Dev的工程师。