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();
            }
        }