public void InitializeCellsArea(PivotLayoutProvider layout)
        {
            CellInfo old_FocusedCellView = FocusedCellView;
            IDictionary<String, MemberInfo> old_tuple = new Dictionary<String, MemberInfo>();
            if (old_FocusedCellView != null)
            {
                old_tuple = old_FocusedCellView.GetTuple();
            }
            CellControl new_FocusedCell = null;

            if (FocusedCell != null)
                FocusedCell.IsFocused = false;

            m_CellControls_Dict.Clear();

            CellChangesCache recalculatedCache = OlapTransactionManager.GetPendingChanges(Connection);
            //int columnIndex = CellsArea_FirstVisible_Coordinate.Column;
            int columnIndex = CellsArea_FirstVisible_Coordinate.Column;

            int layout_column_indx = 0;
            int layout_row_indx = 0;

            bool hasColumnsArea = true;
            int columnsCount = ColumnsArea_LovestMemberControls.Count;
            // если в результате нет осей, а ячейки есть (select from [Adventure Works]), то они должны отображаться без области колонок
            if (columnsCount == 0 && layout.PivotProvider.Provider.CellSet_Description != null &&
                layout.PivotProvider.Provider.CellSet_Description.Cells.Count > 0)
            {
                // Если колонок в CellSet нет, а ячейки есть, то в сводной таблице будет 1 колонка (без шапки)
                columnsCount = 1;
                columnIndex = -1;
                hasColumnsArea = false;
            }

            int Axis0Coord = -1;
            for(int column = 0; column < columnsCount; column++)
            {
                if(hasColumnsArea && ColumnsArea_LovestMemberControls.Count > column)
                {
                    Axis0Coord = ColumnsArea_LovestMemberControls[column].Member.MemberIndexInAxis;
                }

                int rowIndex = CellsArea_FirstVisible_Coordinate.Row;
                layout_row_indx = 0;
                int rowsCount = RowsArea_LovestMemberControls.Count;

                bool hasRowsArea = true;
                // если в результате только одна ось, ячейки есть. То они должны отображаться без области строк
                if (rowsCount == 0 && layout.PivotProvider.Provider.CellSet_Description != null &&
                    layout.PivotProvider.Provider.CellSet_Description.Cells.Count > 0)
                {
                    // Если строк в CellSet нет, а ячейки есть, то в сводной таблице будет 1 строка (без шапки)
                    rowsCount = 1;
                    rowIndex = -1;
                    hasRowsArea = false;
                }

                int Axis1Coord = -1;
                for (int row = 0; row < rowsCount; row++)
                {
                    if (hasRowsArea && RowsArea_LovestMemberControls.Count > row)
                    {
                        Axis1Coord = RowsArea_LovestMemberControls[row].Member.MemberIndexInAxis;
                    }

                    CellInfo cell_info = layout.PivotProvider.Provider.GetCellInfo(Axis0Coord, Axis1Coord);
                    //CellInfo cell_info = layout.PivotProvider.Provider.GetCellInfo(columnIndex, rowIndex);

                    if (cell_info != null)
                    {
                        cell_info.CellsArea_Axis0_Coord = CellsArea_FirstVisible_Coordinate.Column + column;
                        cell_info.CellsArea_Axis1_Coord = CellsArea_FirstVisible_Coordinate.Row + row;

                        CellControl cell_Control = m_CellControls_Cache[layout_column_indx, layout_row_indx];

                        if (cell_Control != null)
                        {
                            m_CellControls_Dict.Add(cell_info, cell_Control);
                            // Left border
                            cell_Control.ShowLeftBorder = !hasRowsArea && layout_column_indx == 0;
                            // Up border
                            cell_Control.ShowUpBorder = !hasColumnsArea && layout_row_indx == 0;

                            cell_Control.Cell = cell_info;
                            if (cell_Control.IsFocused)
                            {
                                cell_Control.IsFocused = false;
                            }

                            if (old_FocusedCellView != null && new_FocusedCell == null)
                            {
                                // Определяем ячейку, на которую должен быть установлен фокус.
                                // Ячейки сверяются по совпадению таплов, т.к. в случае скроллинга для FocusedCellView может быть создан другой контрол
                                // В случае нажатия на кнопку Обновить, либо редактирования чеек FocusedCellView содержит элемент из старого источника. Поэтому нужно обновить его при совпадении таплов
                                if (cell_info.CompareByTuple(old_tuple))
                                {
                                    // Обновляем информацию о ячейке с фокусом
                                    if (cell_info != FocusedCellView)
                                    {
                                        FocusedCellView = cell_info;
                                    }
                                    new_FocusedCell = cell_Control;
                                    new_FocusedCell.IsFocused = true;
                                }
                            }

                            // Cell is changed and not Recalculated
                            cell_Control.NotRecalculatedChange = LocalChanges.FindChange(cell_info);
                            // Cell is changed and already Recalculated
                            cell_Control.RecalculatedChange = recalculatedCache.FindChange(cell_info);
                        }
                    }

                    rowIndex++;
                    layout_row_indx++;
                }
                columnIndex++;
                layout_column_indx++;
            }

            // В КЭШе ячеек для остальных ячеек сбрасываем содержимое
            for (int col = layout_column_indx; col < m_CellControls_Cache.Columns_Size; col++)
            {
                for (int row = 0; row < m_CellControls_Cache.Rows_Size; row++)
                {
                    CellControl cell_Control = m_CellControls_Cache[col, row];
                    if (cell_Control != null)
                    {
                        cell_Control.Cell = null;
                    }
                }
            }
            for (int row = layout_row_indx; row < m_CellControls_Cache.Rows_Size; row++)
            {
                for (int col = 0; col < m_CellControls_Cache.Columns_Size; col++)
                {
                    CellControl cell_Control = m_CellControls_Cache[col, row];
                    if (cell_Control != null)
                    {
                        cell_Control.Cell = null;
                    }
                }
            }

            RefreshSelectedCells();
        }
        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);
                                    }
                                }
                            }
                        }
                    }
                }
            }
        }
        public void InitializeRowsArea(PivotLayoutProvider layout)
        {
            foreach (MemberControl ctrl in m_RowsMembers)
            {
                ItemsLayoutRoot.Children.Remove(ctrl);
            }
            m_RowsMembers.Clear();

            RowsArea_LovestMemberControls.Clear();

            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.DrillDownMember += new MemberActionEventHandler(OnDrillDownMember);
                                }

                                if (CellsArea_BeginColumnIndex > 0 && column_indx == CellsArea_BeginColumnIndex - 1)
                                {
                                    if (member_item.IsExtension == false)
                                    {
                                        RowsArea_LovestMemberControls.Add(member_Control);

                                        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);
                                }
                            }
                        }
                    }
                }
            }
        }
        public void Initialize(CellSetDataProvider provider)
        {
            // Ячейка с фокусом содержит элемент из предыдущего CellSetDataProvider. По таплу ныжно найти ей соответствие в новом CellSetDataProvider
            if (FocusedCellView != null)
            {
                if (provider != null)
                {
                    CellInfo info = provider.GetCellInfo(FocusedCellView.CellDescr.Axis0_Coord, FocusedCellView.CellDescr.Axis1_Coord);
                    IDictionary<String, MemberInfo> tuple = FocusedCellView.GetTuple();
                    if(info != null && info.CompareByTuple(tuple))
                    {
                        // Соответствие сразу найдено (в идеале)
                    }
                    else
                    {
                        info = provider.GetCellByTuple(tuple);
                    }
                    FocusedCellView = info;
                }
                else
                    FocusedCellView = null;
            }

            bool stick = false;
            // Пытаемся получить ячейку, которая в текущий момент верхняя левая
            // и сравнить ее с новой ячейкой с теми же координатами. Если ячейки совпадают, то позицию не обнуляем чтобы на экране осталась текущая область
            if (m_CellSetProvider != null &&
                m_CellSetProvider.CellSet_Description != null)
            {
                CellInfo cell_old = m_CellSetProvider.GetCellInfo(ColumnsArea_FirstVisible_Coordinate.Column, RowsArea_FirstVisible_Coordinate.Row);
                if (cell_old != null)
                {
                    if (provider != null &&
                        provider.CellSet_Description != null)
                    {
                        CellInfo cell_new = provider.GetCellInfo(ColumnsArea_FirstVisible_Coordinate.Column, RowsArea_FirstVisible_Coordinate.Row);
                        if (cell_new != null)
                        { 
                            // Сверяем по координатам
                            stick = cell_new.CompareByTuple(cell_old.GetTuple());
                        }
                    }
                }
            }

            //// Если в старой позиции уже находится другая ячейка, то отображаем ячейку с фокусом
            //if (!stick)
            //{
            //    GoToFocusedCell();
            //    //ColumnsArea_FirstVisible_Coordinate.Column = 0;
            //    //RowsArea_FirstVisible_Coordinate.Row = 0;
            //    //m_VerticalScroll.Value = 0;
            //    //m_HorizontalScroll.Value = 0;
            //}

            m_SelectionManager.ClearSelection();

            //m_MembersWidthes.Clear();
            //m_MembersHeightes.Clear();

            ColumnsArea_LovestMemberControls.Clear();
            RowsArea_LovestMemberControls.Clear();
            m_MemberControls_Dict.Clear();

            DateTime start = DateTime.Now;
            //System.Diagnostics.Debug.WriteLine("PivotGrid initializing start: " + start.TimeOfDay.ToString());

            bool new_OlapData = m_CellSetProvider != provider;
            m_CellSetProvider = provider;
            m_LayoutProvider = null;

            if (provider != null)
            {
                PivotDataProvider pivotProvider = new PivotDataProvider(provider);
                m_LayoutProvider = new PivotLayoutProvider(pivotProvider);
            }

            if (m_AnalyticInfo == null)
                m_AnalyticInfo = new PivotDataAnalizer(this);
            else
            {
                m_AnalyticInfo.ClearMembersAnalytic();
                if (new_OlapData)
                    m_AnalyticInfo.BuildCellsAnalytic();
            }

            Refresh(RefreshType.BuildEndRefresh);

            // Если в старой позиции уже находится другая ячейка, то отображаем ячейку с фокусом
            if (!stick)
            {
                GoToFocusedCell();
            }
            DateTime stop = DateTime.Now;
            //System.Diagnostics.Debug.WriteLine("PivotGrid initializing stop: " + stop.TimeOfDay.ToString());
            //System.Diagnostics.Debug.WriteLine("PivotGrid initializing time: " + (stop - start).ToString());
        }
        public void InitializeColumnsArea(PivotLayoutProvider layout)
        {
            foreach (MemberControl ctrl in m_ColumnsMembers)
            {
                ItemsLayoutRoot.Children.Remove(ctrl);
            }
            m_ColumnsMembers.Clear();

            ColumnsArea_LovestMemberControls.Clear();
            
            int start_ColumnIndex = CellsArea_BeginColumnIndex;
            for (int column_indx = 0, layout_column_indx = start_ColumnIndex; layout_column_indx < ItemsLayoutRoot.ColumnDefinitions.Count; column_indx++, layout_column_indx++)
            {
                ColumnDefinition col = ItemsLayoutRoot.ColumnDefinitions[layout_column_indx];
                if (col == m_Fictive_Column)
                    continue;

                for (int row_indx = 0; row_indx < layout.ColumnsLayout.Rows_Size; row_indx++)
                {
                    // !!!
                    LayoutCellWrapper cell_wrapper = layout.ColumnsLayout[ColumnsArea_FirstVisible_Coordinate.Column + column_indx, ColumnsArea_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 && column_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 ColumnMemberControl(this, member_item.PivotMember.Member, member_item.PivotMember.PivotDrillDepth);
                                    m_MemberControls_Dict.Add(member_item.PivotMember.Member, member_Control);

                                    // Подписываемся на Drill-операцию
                                    member_Control.DrillDownMember += new MemberActionEventHandler(OnDrillDownMember);
                                }

                                if (CellsArea_BeginRowIndex > 0 && row_indx == CellsArea_BeginRowIndex - 1)
                                {
                                    if (member_item.IsExtension == false)
                                    {
                                        ColumnsArea_LovestMemberControls.Add(member_Control);

                                        if (m_Vertiacal_Splitters.ContainsKey(layout_column_indx))
                                        {
                                            m_Vertiacal_Splitters[layout_column_indx].Tag = member_Control;
                                            //Canvas.SetZIndex(m_Vertiacal_Splitters[layout_column_indx], 10);
                                        }
                                    }
                                }

                                m_ColumnsMembers.Add(member_Control);

                                ItemsLayoutRoot.Children.Add(member_Control);
                                Grid.SetColumn(member_Control, layout_column_indx);
                                Grid.SetColumnSpan(member_Control, member_item.ColumnSpan);
                                Grid.SetRow(member_Control, row_indx);
                                Grid.SetRowSpan(member_Control, member_item.RowSpan);

                                if (member_item.PivotMember.IsFirstDrillDownChild || (column_indx == 0/* && member_item.IsExtension == false*/))
                                {
                                    member_Control.ShowLeftBorder(true);
                                }
                                else
                                {
                                    member_Control.ShowLeftBorder(false);
                                }

                                if (row_indx == 0 || member_item.PivotMember.PivotDrillDepth > 0)
                                {
                                    member_Control.ShowUpBorder(true);
                                }
                                else
                                {
                                    member_Control.ShowUpBorder(false);
                                }
                            }
                        }
                    }
                }
            }
        }