// customize cells
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
        {
            // attach grid event handlers
            SetGrid(grid);

            // get the row/column being created
            var col = grid.Columns[rng.Column];
            var row = grid.Rows[rng.Row];
            var field = row.DataItem as FormField;
            var gr = row as GroupRow;

            // create the cell
            base.CreateCellContent(grid, bdr, rng);
            if (col.BoundPropertyName == "Value" && gr == null)
            {
                if (!string.IsNullOrEmpty(field.Formula))
                {
                    _calculatedStyle.Apply(bdr, SelectedState.None);
                }
                else
                {
                    _editStyle.Apply(bdr, SelectedState.None);
                    if (!field.IsString)
                    {
                        _numberStyle.Apply(bdr, SelectedState.None);
                    }
                }
            }
        }
 public SelectedState GetSelectedState(CellRange rng)
 {
     CellRange selection = _grid.Selection;
     if (rng.Contains(selection.Row, selection.Column))
     {
         return SelectedState.Cursor;
     }
     if (_grid.Rows.IsSelected(rng.Row) || _grid.Columns.IsSelected(rng.Column))
     {
         return SelectedState.Selected;
     }
     selection = AdjustSelection(selection, true);
     if (rng.Row < 0 && selection.ContainsColumn(rng.Column) || rng.Column < 0 && selection.ContainsRow(rng.Row))
     {
         return SelectedState.Selected;
     }
     if (_grid.SelectionMode == SelectionMode.ListBox)
     {
         return SelectedState.None;
     }
     if (!rng.Intersects(selection))
     {
         return SelectedState.None;
     }
     return SelectedState.Selected;
 }
Example #3
0
        public CellRange GetMergedRange(C1FlexGrid grid, CellType cellType, CellRange rg)
        {
            // we are only interested in data cells
            // (not merging row or column headers)
            if (cellType == CellType.Cell)
            {
                // expand left/right
                for (int i = rg.Column; i < grid.Columns.Count - 1; i++)
                {
                    if (GetDataDisplay(grid, rg.Row, i) != GetDataDisplay(grid, rg.Row, i + 1)) break;
                    rg.Column2 = i + 1;
                }
                for (int i = rg.Column; i > 0; i--)
                {
                    if (GetDataDisplay(grid, rg.Row, i) != GetDataDisplay(grid, rg.Row, i - 1)) break;
                    rg.Column = i - 1;
                }

                // expand up/down
                for (int i = rg.Row; i < grid.Rows.Count - 1; i++)
                {
                    if (GetDataDisplay(grid, i, rg.Column) != GetDataDisplay(grid, i + 1, rg.Column)) break;
                    rg.Row2 = i + 1;
                }
                for (int i = rg.Row; i > 0; i--)
                {
                    if (GetDataDisplay(grid, i, rg.Column) != GetDataDisplay(grid, i - 1, rg.Column)) break;
                    rg.Row = i - 1;
                }
            }

            // done
            return rg;
        }
Example #4
0
 /// <summary>
 ///     Gets a <see cref="T:C1.WPF.FlexGrid.CellRange" /> that specifies the merged extent of a cell
 ///     in a <see cref="T:C1.WPF.FlexGrid.GridPanel" />.
 /// </summary>
 /// <param name="grid">
 ///     <see cref="T:C1.WPF.FlexGrid.C1FlexGrid" /> that contains the merged cell.
 /// </param>
 /// <param name="cellType">
 ///     <see cref="T:C1.WPF.FlexGrid.CellType" /> that specifies the type of the merged cell.
 /// </param>
 /// <param name="rng">A <see cref="T:C1.WPF.FlexGrid.CellRange" /> that specifies the coordinates of the cell to be merged.</param>
 /// <returns>
 ///     A <see cref="T:C1.WPF.FlexGrid.CellRange" /> that expands the given <paramref name="rng" /> over a merged
 ///     range.
 /// </returns>
 /// <remarks>
 ///     This method expands ranges by comparing the cell contents with the content of neighboring
 ///     cells and merging cells that have the same content.
 /// </remarks>
 public virtual CellRange GetMergedRange(C1FlexGrid grid, CellType cellType, CellRange rng)
 {
     switch (cellType)
     {
         case CellType.Cell:
         {
             if (grid.ActiveEditor != null && grid.EditorRange.Contains(rng))
             {
                 return grid.EditorRange;
             }
             if (grid.GetChildItemsPropertyInfo() != null)
             {
                 return rng;
             }
             return GetMergedRange(grid, grid.Cells, rng);
         }
         case CellType.ColumnHeader:
         {
             return GetMergedRange(grid, grid.ColumnHeaders, rng);
         }
         case CellType.RowHeader:
         {
             return GetMergedRange(grid, grid.RowHeaders, rng);
         }
         case CellType.TopLeft:
         {
             return GetMergedRange(grid, grid.TopLeftCells, rng);
         }
     }
     return rng;
 }
Example #5
0
 internal MouseHandler(C1FlexGrid grid)
 {
     _grid = grid;
     CellRange empty = CellRange.Empty;
     CellRange cellRange = empty;
     _dragTarget = empty;
     _cellResize = cellRange;
     _tmScroll = new Timer();
     _tmScroll.Tick += OnDragTimerTick;
     _tmScroll.Interval = TimeSpan.FromMilliseconds(SCROLL_DELAY);
     _dragHelper = new C1DragHelper(_grid,
         C1DragHelperMode.TranslateX | C1DragHelperMode.TranslateY | C1DragHelperMode.TranslateXY | C1DragHelperMode.Inertia | C1DragHelperMode.TranslateRailX |
         C1DragHelperMode.TranslateRailY, 1, false, false, false, false);
     _dragHelper.DragStarting += OnDragStarting;
     _dragHelper.DragStarted += OnDragStarted;
     _dragHelper.DragDelta += OnDragDelta;
     _dragHelper.DragCompleted += OnDragCompleted;
     _dragHelper.DragInertiaStarted += OnDragInertiaStarted;
     C1TapHelper c1TapHelper = new C1TapHelper(_grid, false);
     c1TapHelper.Tapped += OnTapped;
     c1TapHelper.DoubleTapped += OnDoubleTapped;
     _grid.KeyDown += OnKeyDown;
     _grid.MouseWheel += OnWheelChanged;
     _grid.MouseMove += OnMouseMove;
     _grid.AddHandler(UIElement.MouseLeftButtonUpEvent, new MouseButtonEventHandler(OnMouseLeftButtonUp), true);
     _grid.AddHandler(UIElement.MouseLeftButtonDownEvent, new MouseButtonEventHandler(OnMouseLeftButtonDown), true);
 }
        public override void CreateColumnHeaderContent(C1FlexGrid grid, Border bdr, CellRange range)
        {
            base.CreateColumnHeaderContent(grid, bdr, range);

            //var row = grid.Rows[range.Row];
            //var column = grid.Columns[range.Column];
            //var propertyInfo = column.PropertyInfo;

            //CustomColumnHeader header =new CustomColumnHeader();


            //Binding nameBinding = new Binding();
            //nameBinding.Path = new PropertyPath("HeaderName");
            //header.SetBinding(CustomColumnHeader.HeaderNameProperty, nameBinding);

            //Binding tooltipBinding = new Binding();
            //tooltipBinding.Path = new PropertyPath("HeaderName");
            //header.SetBinding(CustomColumnHeader.HeaderTooltipProperty, tooltipBinding);


            //bdr.Child = header;
            //bdr.Padding = _thicknessEmpty;
            //bdr.HorizontalAlignment = HorizontalAlignment.Stretch;

            //header.HeaderName = propertyInfo.Name;
            //header.HeaderToolTip = propertyInfo.Name;

            //// traditional binding
            //var binding = new Binding(propertyInfo.Name);
            //binding.Source = grid.ColumnHeaders;
            //binding.Mode = BindingMode.OneWay;
            //header.SetBinding(CustomColumnHeader.HeaderNameProperty, binding);
        }
        // bind cell to ticker
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange range)
        {
            // create binding for this cell
            var r = grid.Rows[range.Row];
            var c = grid.Columns[range.Column];
            var pi = c.PropertyInfo;
            if (r.DataItem is FinancialData &&
               (pi.Name == "LastSale" || pi.Name == "Bid" || pi.Name == "Ask"))
            {
                // create stock ticker cell
                StockTicker ticker = new StockTicker();
                bdr.Child = ticker;
                bdr.Padding = _thicknessEmpty;

                // to show sparklines
                ticker.Tag = r.DataItem;
                ticker.BindingSource = pi.Name;

                // traditional binding
                var binding = new Binding(pi.Name);
                binding.Source = r.DataItem;
                binding.Mode = BindingMode.OneWay;
                ticker.SetBinding(StockTicker.ValueProperty, binding);
            }
            else
            {
                // use default implementation
                base.CreateCellContent(grid, bdr, range);
            }
        }
 public override void CreateRowHeaderContent(C1FlexGrid grid, Border bdr, CellRange range)
 {
     var tb = new TextBlock();
     tb.HorizontalAlignment = HorizontalAlignment.Center;
     tb.VerticalAlignment = VerticalAlignment.Center;
     tb.Text = string.Format("{0}", range.Row + 1);
     bdr.Child = tb;
 }
 // override horizontal alignment to make ticker cell stretch and fill the column width
 public override void ApplyCellStyles(C1FlexGrid grid, CellType cellType, CellRange range, Border bdr)
 {
     var ticker = bdr.Child as StockTicker;
     if (ticker != null)
     {
         ticker.HorizontalAlignment = HorizontalAlignment.Stretch;
     }
 }
 public override void CreateColumnHeaderContent(C1FlexGrid grid, Border bdr, CellRange range)
 {
     var tb = new TextBlock();
     tb.HorizontalAlignment = HorizontalAlignment.Center;
     tb.VerticalAlignment = VerticalAlignment.Center;
     tb.Text = GetAlphaColumnHeader(range.Column);
     bdr.Child = tb;
 }
        // initialize custom cell editor
        UIElement CreateEditor(Type t, CellRange rng)
        {
            // create cell element, save range in Tag property
            var edt = Activator.CreateInstance(t) as FrameworkElement;
            edt.Tag = rng;
            edt.VerticalAlignment = VerticalAlignment.Center;

            // get current value from grid
            var value = _flex[rng.Row, rng.Column];

            // initialize each editor type
            var textBox = edt as TextBox;
            if (textBox != null)
            {
                textBox.Text = value is string ? (string)value : string.Empty;
                textBox.LostFocus += StoreCellValue;
            }

            var checkBox = edt as CheckBox;
            if (checkBox != null)
            {
                checkBox.HorizontalAlignment = HorizontalAlignment.Center;
                checkBox.VerticalAlignment = VerticalAlignment.Center;
                checkBox.IsChecked = value is bool ? (bool)value : false;
                checkBox.LostFocus += StoreCellValue;
            }

            var comboBox = edt as ComboBox;
            if (comboBox != null)
            {
                for (int i = 0; i < 5; i++)
                {
                    comboBox.Items.Add("Item " + i.ToString());
                }
                comboBox.SelectedValue = value is string ? (string)value : comboBox.Items[0];
                comboBox.LostFocus += StoreCellValue;
            }

            var slider = edt as Slider;
            if (slider != null)
            {
                slider.Minimum = 0;
                slider.Maximum = 50;
                slider.Value = value is double ? (double)value : 0;
                slider.LostFocus += StoreCellValue;
            }

            var colorPicker = edt as C1ColorPicker;
            if (colorPicker != null)
            {
                colorPicker.SelectedColor = value is Color ? (Color)value : Colors.White;
                colorPicker.SelectedColorChanged += StoreCellValue;
            }

            // done
            edt.VerticalAlignment = VerticalAlignment.Center;
            return edt;
        }
 /// <summary>
 /// Initializes a new instance of an <see cref="CellRangeEditAction"/>.
 /// </summary>
 public CellRangeEditAction(C1FlexGrid flex)
 {
     _flex = flex;
     var sel = _flex.Selection;
     _oldTopRow = sel.TopRow;
     _oldLeftCol = sel.LeftColumn;
     _oldSelection = sel;
     RecordState(ref _oldCellValues, sel);
 }
 // ** object model
 public void AddMergedRange(CellRange rng)
 {
     if (!rng.IsSingleCell)
     {
         RemoveMergedRange(rng);
         _mergedRanges.Add(new CellRange(rng.TopRow, rng.LeftColumn, rng.BottomRow, rng.RightColumn));
         _grid.Invalidate();
     }
 }
        /// <summary>
        /// Applies custom styles to the outline row.
        /// </summary>
        public override void ApplyCellStyles(C1FlexGrid grid, CellType cellType, CellRange range, Border bdr)
        {
            if (cellType == CellType.Cell)
            {
                bool hasAlignment = false;

                // get selection state for the range
                var selState = grid.GetSelectedState(range);

                // apply row style
                var row = grid.Rows[range.Row];
                if (row.CellStyle != null)
                {
                    row.CellStyle.Apply(bdr, selState);
                    hasAlignment |= row.CellStyle.HorizontalAlignment.HasValue;
                }

                // apply column style
                var col = grid.Columns[range.Column];
                if (col.CellStyle != null)
                {
                    col.CellStyle.Apply(bdr, selState);
                    hasAlignment |= col.CellStyle.HorizontalAlignment.HasValue;
                }

                // apply cell style
                var xlr = row as ExcelRow;
                if (xlr != null)
                {
                    var s = xlr.GetCellStyle(col);
                    if (s != null)
                    {
                        // leave hyperlink foreground alone...
                        if (bdr.Child is HyperlinkButton)
                        {
                            s.Foreground = null;
                        }

                        // apply standard CellStyle stuff
                        s.Apply(bdr, selState);
                        hasAlignment |= s.HorizontalAlignment.HasValue;

                        // apply general alignment
                        if (!hasAlignment)
                        {
                            var content = grid[range.Row, range.Column];
                            if (IsNumeric(content))
                            {
                                _styleRight.Apply(bdr, selState);
                            }
                        }
                    }
                }
            }
        }
 public override void CreateTopLeftContent(C1FlexGrid grid, Border bdr, CellRange range)
 {
     var poly = CreatePolygon(0, 10, 10, 10, 10, 0);
     poly.Fill = new SolidColorBrush(Color.FromArgb(0xe0, 0xf5, 0xf5, 0xf5));
     poly.VerticalAlignment = VerticalAlignment.Center;
     poly.HorizontalAlignment = HorizontalAlignment.Right;
     poly.Margin = new Thickness(2);
     bdr.Child = poly;
     bdr.Tag = grid;
     bdr.MouseLeftButtonDown += new MouseButtonEventHandler(bdr_MouseLeftButtonDown);
 }
 public void RemoveMergedRange(CellRange rng)
 {
     for (int i = 0; i < _mergedRanges.Count; i++)
     {
         if (rng.Intersects(_mergedRanges[i]))
         {
             _mergedRanges.RemoveAt(i);
             i--;
         }
     }
     _grid.Invalidate();
 }
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
        {
            // crate the content
            base.CreateCellContent(grid, bdr, rng);

            // add the tooltip
            var tip = string.Format("row: {0} col: {1}\r\ncontent: {2}\r\ncolumn Tag: {3}",
                rng.Row,
                rng.Column,
                grid[rng.Row, rng.Column],
                grid.Columns[rng.Column].Tag);
            ToolTipService.SetToolTip(bdr, tip);
        }
 public override FrameworkElement CreateCell(C1FlexGrid grid, CellType cellType, CellRange rng)
 {
     FrameworkElement frameworkElement = _baseCellFactory.CreateCell(grid, cellType, rng);
     if (cellType == CellType.ColumnHeader)
     {
         Border border = frameworkElement as Border;
         if (border != null)
         {
             CreateColumnHeaderContent(grid, border, rng);
         }
     }
     return frameworkElement;
 }
 // create the custom cell editor
 public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
 {
     var t = GetCellType(rng);
     if (t != null)
     {
         // cell has a custom type, create editor
         bdr.Child = CreateEditor(t, rng);
     }
     else
     {
         // default handling
         base.CreateCellContent(grid, bdr, rng);
     }
 }
        // ** IMergeManager
        public CellRange GetMergedRange(C1FlexGrid grid, CellType cellType, CellRange range)
        {
            // look for merged ranges that contain the given cell
            foreach (var mergedRange in _mergedRanges)
            {
                if (mergedRange.Contains(range))
                {
                    return mergedRange;
                }
            }

            // not found, not merged
            return range;
        }
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange rng)
        {
            base.CreateCellContent(grid, bdr, rng);

            var row = grid.Rows[rng.Row] as GroupRow;
            if (rng.Column == 0 && row != null)
            {
                bdr.Padding = _tEmpty;
                var cellGrid = bdr.Child as Grid;
                cellGrid.Children.RemoveAt(0);
                var treeNode = CreateTreeNode(grid, row);
                cellGrid.Children.Add(treeNode);
            }
        }
        // bind a cell to a range
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange range)
        {
            // get row/col
            var row = grid.Rows[range.Row];
            var col = grid.Columns[range.Column];
            var gr = row as GroupRow;

            // no border for group rows
            if (gr != null)
            {
                bdr.BorderThickness = _emptyThickness;
            }

            // bind the tree cells
            if (gr != null && range.Column == 0)
            {
                BindGroupRowCell(grid, bdr, range);
                return;
            }

            // bind cells in regular data rows
            var colName = col.ColumnName;
            if (colName == "Name")
            {
                bdr.Child = new SongCell(row);
                return;
            }
            if (colName == "Rating")
            {
                var song = row.DataItem as Song;
                if (song != null)
                {
                    // create rating control to represent this cell
                    // notes:
                    // - the data context is provided by the Border element, and
                    // - the binding is provided by the column
                    var cell = new RatingCell();
                    cell.SetBinding(RatingCell.RatingProperty, col.Binding);
                    bdr.Child = cell;
                    return;
                }
            }

            // default binding
            base.CreateCellContent(grid, bdr, range);
        }
        /// <summary>
        /// Records the values of all the cells within the current selection of the <see cref="C1FlexGrid"/>.
        /// </summary>
        /// <param name="values">The array where cell values are stored.</param>
        /// /// <param name="range">The range of cells whose values will be stored.</param>
        void RecordState(ref object[,] values, CellRange range)
        {
            values = new object[range.BottomRow - range.TopRow + 1, range.RightColumn - range.LeftColumn + 1];
            for (int r = range.TopRow; r <= range.BottomRow; r++)
            {
                // skip rows that are not selected
                if (_flex.SelectionMode == SelectionMode.ListBox && !_flex.Rows[r].Selected)
                {
                    continue;
                }

                var row = _flex.Rows[r];
                for (int c = range.LeftColumn; c <= range.RightColumn; c++)
                {
                    var col = _flex.Columns[c];
                    values[r - range.TopRow, c - range.LeftColumn] = row.GetDataRaw(col);
                }
            }
        }
Example #24
0
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange range)
        {
            // get the data object stored in the unbound grid
            var obj = grid[range.Row, range.Column] as MyDataObject;
            if (obj != null)
            {
                // create a custom view object
                var e = new MyViewObject(grid, obj);

                // assign it to the cell
                bdr.Child = e;

                // register cell border as a drag source
                _ddMgr.RegisterDragSource(bdr, DragDropEffect.Move, ModifierKeys.None);
            }
            else
            {
                base.CreateCellContent(grid, bdr, range);
            }
        }
        public override void CreateColumnHeaderContent(C1FlexGrid grid, Border bdr, CellRange range)
        {
            // let base class start
            base.CreateColumnHeaderContent(grid, bdr, range);

            // rotate the content of headers for numeric and Boolean columns
            var type = grid.Columns[range.Column].DataType;
            if (type == typeof(double) || type == typeof(int) || type == typeof(bool))
            {

                var cellContent = bdr.Child as FrameworkElement;
                //Creating a matrix
                 Matrix matrix = new Matrix();
                 matrix.Rotate(-90);
                 cellContent.VerticalAlignment = VerticalAlignment.Center;
                //Assigning matrix to the LayoutTransform
                cellContent.LayoutTransform=new MatrixTransform(matrix);

            }
        }
        public override void CreateCellContent(C1FlexGrid grid, Border bdr, CellRange range)
        {
            try
            {
                var row = grid.Rows[range.Row];
                var column = grid.Columns[range.Column];
                var propertyInfo = column.PropertyInfo;
                if(propertyInfo != null && propertyInfo.Name.Contains("Difference"))
                {
                    // create stock ticker cell
                    TrendTicker ticker = new TrendTicker();
                    bdr.Child = ticker;
                    bdr.Padding = _thicknessEmpty;
                    bdr.HorizontalAlignment = HorizontalAlignment.Stretch;

                    // traditional binding
                    var binding = new Binding(propertyInfo.Name);
                    binding.Source = row.DataItem;
                    binding.Mode = BindingMode.OneWay;
                    ticker.SetBinding(TrendTicker.ValueProperty, binding);
                }
                else
                {
                    // use default implementation
                    base.CreateCellContent(grid, bdr, range);
                }
            }
            catch(Exception ex)
            {
                ShowMessage.Show("创建单元格内容出错");
                LogHelper.LogMessage(MethodBase.GetCurrentMethod().DeclaringType, LogHelper.LogLevel, "Failed to CreateCellContent", ex);
            }
            finally
            {
                if(LogHelper.LogLevel == LogLevelEnum.Debug || LogHelper.LogLevel == LogLevelEnum.Info)
                {
                    LogHelper.LogMessage(MethodBase.GetCurrentMethod().DeclaringType, LogHelper.LogLevel, "CreateCellContent", null);
                }
            }
        }
Example #27
0
        public override FrameworkElement CreateCell(C1FlexGrid grid, CellType cellType, CellRange range)
        {
            // let base class to most of the work
            var cell = base.CreateCell(grid, cellType, range);

            // keep the selectionbackground
            if (grid.GetSelectedState(range) != SelectedState.None)
                return cell;

            // apply green background if necessary
            if (cellType == CellType.Cell)
            {
                var cellValue = grid[range.Row, range.Column];
                if (cellValue is double && (double)cellValue > 500)
                {
                    var border = cell as Border;
                    border.Background = _greenBrush;
                }
            }

            // done
            return cell;
        }
Example #28
0
        public override void CreateCellContent(C1FlexGrid grid, System.Windows.Controls.Border bdr, CellRange rng)
        {
            if (grid.Cells[rng.Row, rng.Column] is bool)
            {

                // it does, so create a checkbox to show/edit the value
                CheckBox chk = new CheckBox();
                 chk.IsChecked =(bool?)grid.Cells[rng.Row, rng.Column];
                chk.VerticalAlignment = VerticalAlignment.Center;
                chk.HorizontalAlignment = HorizontalAlignment.Center;
                ToolTipService.SetToolTip(chk, "This CheckBox represents a boolean value stored in a grid cell.");

                // assign the checkbox to the cell element (a Border)
                bdr.Child = chk;

                // connect the checkbox so it updates the content of the grid cell
                chk.Tag = grid;
                chk.AddHandler(CheckBox.ClickEvent, new RoutedEventHandler(chk_Click));

            }
            else if (grid.Cells[rng.Row, rng.Column] is Control)
            {
                // add the control to the cell (if it doesn't have a parent)
                Control ctl = (Control)grid.Cells[rng.Row, rng.Column];
                if (ctl.Parent == null)
                {
                      bdr.Child =(System.Windows.Controls.Control) grid.Cells[rng.Row, rng.Column];
                }

            }
            else
            {
                // not a boolean, allow default behavior
                base.CreateCellContent(grid, bdr, rng);

            }
        }
        // overridden to apply the custom brushes based on the cell value
        public override void ApplyCellStyles(C1FlexGrid grid, CellType cellType, CellRange range, Border bdr)
        {
            // we are interested only in data cells (no headers)
            if (cellType == CellType.Cell)
            {
                // we are interested in double values only
                var col = grid.Columns[range.Column];
                if (col.DataType == typeof(double))
                {
                    // get the cell value
                    var value = (double)grid[range.Row, col];

                    // apply formatting if value is out of range
                    if (value < 10 || value > 100)
                    {
                        var tb = bdr.Child as TextBlock;
                        if (tb != null)
                        {
                            tb.Foreground = value < 10 ? _brLowValue : _brHighValue;
                        }
                    }
                }
            }
        }
Example #30
0
 private CellRange UpdateDragTargetCell(RoutedEventArgs e, HitTestInfo htDown)
 {
     GridPanel panel = htDown.Panel;
     HitTestInfo hitTestInfo = panel.HitTest(e);
     switch (hitTestInfo.CellType)
     {
         case CellType.ColumnHeader:
         {
             _grid.ScrollIntoView(-1, hitTestInfo.Column);
             int col = (int) _rcInsert.GetValue(Grid.ColumnProperty);
             int dst = GetValidDestination(panel.Columns, col, hitTestInfo.Column);
             Rect cellRect = panel.GetCellRect(htDown.Row, dst);
             if (hitTestInfo.Point.X <= cellRect.X + cellRect.Width/2)
             {
                 cellRect.X = cellRect.X - 2;
             }
             else
             {
                 cellRect.X = cellRect.Right - 2;
                 dst++;
             }
             cellRect.Width = 3;
             _rcInsert.Arrange(cellRect);
             _dragTarget.SetRange(-1, dst);
             break;
         }
         case CellType.RowHeader:
         {
             _grid.ScrollIntoView(hitTestInfo.Row, -1);
             int row = (int) _rcInsert.GetValue(Grid.RowProperty);
             int dst = GetValidDestination(panel.Rows, row, hitTestInfo.Row);
             Rect y = panel.GetCellRect(dst, htDown.Column);
             if (hitTestInfo.Point.Y <= y.Y + y.Height/2)
             {
                 y.Y = y.Y - 2;
             }
             else
             {
                 y.Y = y.Bottom - 2;
                 dst++;
             }
             y.Height = 3;
             _rcInsert.Arrange(y);
             _dragTarget.SetRange(dst, -1);
             break;
         }
     }
     CellRange cellRange = new CellRange(_rcHighlight);
     _rcHighlight.Arrange(panel.GetCellRect(cellRange));
     return _dragTarget;
 }
        // highlight hot cell using two red arrows
        public override void CreateCellContent(C1.WPF.FlexGrid.C1FlexGrid grid, Border bdr, C1.WPF.FlexGrid.CellRange range)
        {
            base.CreateCellContent(grid, bdr, range);
            if (HotRange.Contains(range))
            {
                // save original content
                var child = bdr.Child;
                bdr.Child = null;

                // create grid to hold content and two red arrows
                var g = new Grid();
                g.ColumnDefinitions.Add(new ColumnDefinition()
                {
                    Width = new GridLength(1, GridUnitType.Auto)
                });
                g.ColumnDefinitions.Add(new ColumnDefinition());
                g.ColumnDefinitions.Add(new ColumnDefinition()
                {
                    Width = new GridLength(1, GridUnitType.Auto)
                });

                // set content
                child.SetValue(Grid.ColumnProperty, 1);
                g.Children.Add(child);

                // set left arrow
                var p1 = new Polygon();
                p1.Points            = _leftArrow;
                p1.Fill              = _arrowBrush;
                p1.VerticalAlignment = VerticalAlignment.Center;
                g.Children.Add(p1);

                // set right arrow
                var p2 = new Polygon();
                p2.Points            = _rightArrow;
                p2.Fill              = _arrowBrush;
                p2.VerticalAlignment = VerticalAlignment.Center;
                p2.SetValue(Grid.ColumnProperty, 2);
                g.Children.Add(p2);

                // assign new content to cell
                bdr.Child = g;
            }
        }