public void InitializeRowsArea(PivotLayoutProvider layout) { foreach (MemberControl ctrl in m_RowsMembers) { ItemsLayoutRoot.Children.Remove(ctrl); } m_RowsMembers.Clear(); for(int c = 0; c < m_RowsArea_Splitters.Columns_Size; c++) for(int r = 0; r < m_RowsArea_Splitters.Rows_Size; r++) { var splitter = m_RowsArea_Splitters[c, r]; if(splitter != null) { ItemsLayoutRoot.Children.Remove(splitter); } } m_RowsArea_Splitters = new Cache2D<GridSplitter>(); RowsArea_LovestMemberControls.Clear(); // Получаем сортировку по значению для противоположной оси SortByValueDescriptor value_sort = null; if (QueryManager != null) { value_sort = (AxisIsRotated == false ? QueryManager.Axis0_MeasuresSort : QueryManager.Axis1_MeasuresSort) as SortByValueDescriptor; } int start_RowIndex = CellsArea_BeginRowIndex; for (int column_indx = 0; column_indx < layout.RowsLayout.Columns_Size; column_indx++) { for (int row_indx = 0, layout_row_indx = start_RowIndex; layout_row_indx < ItemsLayoutRoot.RowDefinitions.Count; row_indx++, layout_row_indx++) { RowDefinition row = ItemsLayoutRoot.RowDefinitions[layout_row_indx]; if (row == m_Fictive_Row) continue; // !!! LayoutCellWrapper cell_wrapper = layout.RowsLayout[RowsArea_FirstVisible_Coordinate.Column + column_indx, RowsArea_FirstVisible_Coordinate.Row + row_indx]; if (cell_wrapper != null) { foreach (LayoutItem item in cell_wrapper.Items) { MemberControl member_Control = null; MemberLayoutItem member_item = item as MemberLayoutItem; if (member_item != null && (member_item.IsExtension == false || (member_item.IsExtension == true && row_indx == 0))) { if (m_MemberControls_Dict.ContainsKey(member_item.PivotMember.Member)) { member_Control = m_MemberControls_Dict[member_item.PivotMember.Member]; } if (member_Control == null) { member_Control = new RowMemberControl(this, member_item.PivotMember.Member, member_item.PivotMember.PivotDrillDepth); m_MemberControls_Dict.Add(member_item.PivotMember.Member, member_Control); // Подписываемся на Drill-операцию member_Control.ExecuteMemberAction += new MemberActionEventHandler(OnExecuteMemberAction); } if (CellsArea_BeginColumnIndex > 0 && column_indx == CellsArea_BeginColumnIndex - 1) { if (member_item.IsExtension == false) { RowsArea_LovestMemberControls.Add(member_Control); // Определяем сортирована ли данная колонка if (value_sort != null && value_sort.Type != SortTypes.None) { // Сортирована ли по данному элементу if (value_sort.CompareByTuple(member_item.PivotMember.Member.GetAxisTuple())) { member_Control.SortByValueType = value_sort.Type; } } //if (m_Horizontal_Splitters.ContainsKey(layout_row_indx)) //{ // m_Horizontal_Splitters[layout_row_indx].Tag = member_Control; // //Canvas.SetZIndex(m_Horizontal_Splitters[layout_row_indx], 10); //} } } m_RowsMembers.Add(member_Control); //if(member_item.IsExtension) // member_Control.RenderTransform = new RotateTransform() { Angle = -90 /*CenterY = -20*/ }; ItemsLayoutRoot.Children.Add(member_Control); Grid.SetColumn(member_Control, column_indx); Grid.SetColumnSpan(member_Control, member_item.ColumnSpan); Grid.SetRow(member_Control, layout_row_indx); Grid.SetRowSpan(member_Control, member_item.RowSpan); if ((member_item.PivotMember.IsFirstDrillDownChild && member_item.IsExtension == false) || (row_indx == 0/* && member_item.IsExtension == false*/)) { member_Control.ShowUpBorder= true; //if (member_item.IsExtension) //{ // member_Control.Opacity = 0.3; //} } else { member_Control.ShowUpBorder = false; } member_Control.RotateCaption(member_item.IsExtension); if (column_indx == 0 || member_item.PivotMember.PivotDrillDepth > 0) { member_Control.ShowLeftBorder = true; } else { member_Control.ShowLeftBorder = false; } // Если элемент размером на несколько строк, то сплиттер добавляем на последнюю строку int cells_area_index = row_indx + (member_item.RowSpan > 1 ? (member_item.RowSpan - 1) : 0); var splitter = Add_HorzSplitter(ItemsLayoutRoot, column_indx, RowsArea_BeginRowIndex + cells_area_index, 1); splitter.Margin = new Thickness(member_Control.Margin.Left, 0, 0, 0); m_RowsArea_Splitters.Add(splitter, column_indx, cells_area_index); // Чтобы сплиттер для элемента не накладывался на DrillDown родителя if (row_indx > 0) { // Левое смещение сплиттера должно быть как смещение следующего за сплиттером контрола var prev_member_splitter = m_RowsArea_Splitters[column_indx, row_indx - 1]; if (prev_member_splitter != null) { prev_member_splitter.Margin = new Thickness(member_Control.Margin.Left, 0, 0, 0); } else { // Если сплиттер на предыдущей строке разметки не найден, то добавим его prev_member_splitter = Add_HorzSplitter(ItemsLayoutRoot, column_indx, RowsArea_BeginRowIndex + row_indx - 1, 1); prev_member_splitter.Margin = new Thickness(member_Control.Margin.Left, 0, 0, 0); m_RowsArea_Splitters.Add(prev_member_splitter, column_indx, row_indx - 1); } } } } } } } }
void BuildAreasLayout() { m_ColumnsArea_ColumnsCount = 0; m_ColumnsArea_RowsCount = 0; m_RowsArea_ColumnsCount = 0; m_RowsArea_RowsCount = 0; // Чистим кэш ячеек m_CellControls_Cache = new Cache2D<CellControl>(); ItemsLayoutRoot.Children.Clear(); ItemsLayoutRoot.ColumnDefinitions.Clear(); ItemsLayoutRoot.RowDefinitions.Clear(); m_Vertiacal_Splitters.Clear(); m_Horizontal_Splitters.Clear(); if (m_LayoutProvider != null) { PivotLayoutProvider layout = m_LayoutProvider; #region Область строк // Создаем колонки, которые будут отведены под область строк for (int i = 0; i < layout.RowsLayout.Columns_Size; i++) { ColumnDefinition current_column = new ColumnDefinition() { Width = GridLength.Auto }; if (m_Rows_ColumnWidthes.ContainsKey(i)) { current_column.Width = new GridLength(m_Rows_ColumnWidthes[i]); } ItemsLayoutRoot.ColumnDefinitions.Add(current_column); } // Настраиваем ширины колонок для области строк for (int i = 0; i < layout.RowsLayout.Columns_Size; i++) { ColumnDefinition current_column = ItemsLayoutRoot.ColumnDefinitions[i + PivotArea_BeginColumnIndex]; int column_index_in_area = i; Dictionary<int, int> drillDepth = layout.PivotProvider.RowsArea.DrillDepth; if (AutoWidthColumns && m_AnalyticInfo != null) { // Расширяем колонку с учетом заглубления в ней double width = (DRILLDOWN_SPACE_WIDTH * drillDepth[column_index_in_area] + m_AnalyticInfo.GetEstimatedColumnSizeForRowsArea(column_index_in_area) + 10 + 10 * Scale) * Scale; // 10-для красоты, 10* - на плюсики if (drillDepth.ContainsKey(column_index_in_area)) current_column.Width = new GridLength(Math.Round(Math.Max(DEFAULT_WIDTH * Scale, width))); else current_column.Width = new GridLength(Math.Round(DEFAULT_WIDTH * Scale)); if (drillDepth.ContainsKey(column_index_in_area)) current_column.MinWidth = Math.Round((DRILLDOWN_SPACE_WIDTH * drillDepth[column_index_in_area] + MIN_WIDTH) * Scale); else current_column.MinWidth = Math.Round(MIN_WIDTH * Scale); } else { // Вычисляем максимальное заглубление по данной колонке if (drillDepth.ContainsKey(column_index_in_area)) { // Расширяем колонку с учетом заглубления в ней double width = (DEFAULT_WIDTH + DRILLDOWN_SPACE_WIDTH * drillDepth[column_index_in_area]) * Scale; current_column.Width = new GridLength(Math.Max(current_column.Width.Value, width)); current_column.MinWidth = Math.Round((DRILLDOWN_SPACE_WIDTH * drillDepth[column_index_in_area] + MIN_WIDTH) * Scale); } else { current_column.Width = new GridLength(Math.Round(DEFAULT_WIDTH * Scale)); current_column.MinWidth = Math.Round(MIN_WIDTH * Scale); } } } #endregion Область строк #region Область колонок // Создаем строки, которые будут отверены под область колонок for (int i = 0; i < layout.ColumnsLayout.Rows_Size; i++) { RowDefinition current_row = new RowDefinition() { Height = GridLength.Auto }; if (m_Columns_RowsHeightes.ContainsKey(i)) { current_row.Height = new GridLength(m_Columns_RowsHeightes[i]); } ItemsLayoutRoot.RowDefinitions.Add(current_row); } // Настраиваем высоты строк для области колонок for (int i = 0; i < layout.ColumnsLayout.Rows_Size; i++) { RowDefinition current_row = ItemsLayoutRoot.RowDefinitions[i + PivotArea_BeginRowIndex]; int row_index_in_area = i; Dictionary<int, int> drillDepth = layout.PivotProvider.ColumnsArea.DrillDepth; // Вычисляем максимальное заглубление по данной строке if (drillDepth.ContainsKey(row_index_in_area)) { // Делаем строку выше с учетом заглубления в ней double height = (DEFAULT_HEIGHT + DRILLDOWN_SPACE_HEIGHT * drillDepth[row_index_in_area]) * Scale; current_row.Height = new GridLength(Math.Round(Math.Max(current_row.Height.Value, height))); current_row.MinHeight = Math.Round((DRILLDOWN_SPACE_HEIGHT * drillDepth[row_index_in_area] + MIN_HEIGHT) * Scale); } else { current_row.Height = new GridLength(Math.Round(DEFAULT_HEIGHT * Scale)); current_row.MinHeight = Math.Round(MIN_HEIGHT * Scale); } } #endregion Область колонок // Число колонок в области строк и число строк в области колонок останутся неизменными при любых манипуляциях с данным представлением m_RowsArea_ColumnsCount = ItemsLayoutRoot.ColumnDefinitions.Count; m_ColumnsArea_RowsCount = ItemsLayoutRoot.RowDefinitions.Count; UpdateLayout(); } }