FlexGrid group panel drag and drop UX

Posted by: egor.kachiguine on 13 December 2018, 5:58 am EST

    • Post Options:
    • Link

    Posted 13 December 2018, 5:58 am EST

    The existing UI for using the group panel is a bit bare-bones. I’d like to add some more user feed back - maybe a button-style “click” effect on the mousedown and maybe a drag and drop effect - for example like in the devexpress version of the grid:

    https://www.youtube.com/watch?v=2TL_EFfxcGs

    Do you guys have any resources for theming these sorts of things? Where should I start?

  • Posted 14 December 2018, 6:16 am EST

    Hi,

    FlexGrid does not provide any resources to achieve such effects however, you can get them by simply writing few lines of code.

    In order to have ColumnHeader to be reactive to mouse events, you can use custom CellFactory and override CreateColumnHeaderContent method as follows:

    
    public override void CreateColumnHeaderContent(C1FlexGrid grid, Border bdr, CellRange rng)
    {
     base.CreateColumnHeaderContent(grid, bdr, rng);
     defaultHeaderBrush = bdr.Background;
     bdr.MouseEnter += CustomCellFactory_MouseEnter;
     bdr.MouseLeave += CustomCellFactory_MouseLeave;
    }
    
    

    And for Drag-Drop effect you can use DraggingColumn event on FlexGrid as follows:

    
    private void FlexGrid_DraggingColumn(object sender, C1.WPF.FlexGrid.CellRangeEventArgs e)
    {
     if (canvas == null)
     {
      canvas = new Canvas();
      Grid.SetRow(canvas, 0);
      Grid.SetRowSpan(canvas, 2);
     }
     grid.Children.Add(canvas);
    //Use TextBlock to create shadow effect
     var tb = new TextBlock() { Background = new SolidColorBrush(Color.FromArgb(50, 100, 100, 100)), Text = flexGrid.Columns[e.Column].ColumnName };
     tb.Width = (flexGrid.Columns[e.Column].ActualWidth);
     tb.Height = (flexGrid.ColumnHeaders.ActualHeight);
     
     var position = Mouse.GetPosition(canvas);
     var hitTest = flexGrid.HitTest(position);
     var shiftPoint = new Point(position.X - hitTest.Rect.X - flexGrid.RowHeaders.ActualWidth, Mouse.GetPosition(flexGrid).Y);
     canvas.Tag = shiftPoint;
     tb.Margin = new Thickness(position.X - shiftPoint.X, position.Y - shiftPoint.Y, 0, 0);
    
     canvas.Children.Add(tb);
    }
    
    

    Please refer the attached sample (prj_GroupPanelStyling.zip) for complete implementation of the same.

    Thanks and Regards,

    Basant

    prj_GroupPanelStyling.zip

  • Posted 14 December 2018, 7:13 am EST

    Thanks for the example, I think I can make this work like I want it to.

  • Posted 18 December 2018, 6:17 am EST

    Hi - I’m having a bit of an issue implementing this in our project. I don’t think it’s a FlexGrid issue, but maybe you can shed some light on what’s going on. Basically, when you have this control nested, the MouseUp event gets trapped higher in the visual tree and doesn’t register. This can be solved by using the root grid as the parent for the canvas element.

    But when there are rows on that parent grid, you immediately get an error I don’t quite understand, in user32.dll. Any idea what is happening here? Example attached. GroupPanelStyling - Copy.zip

  • Posted 18 December 2018, 8:42 am EST - Updated 4 October 2022, 12:09 am EST

    The problem seems to be that in that circumstance, FlexGrid.HitTest returns some odd data, with the rectangle being incomplete.

    So you get an infinity in the shiftpoint.

  • Posted 18 December 2018, 3:47 pm EST

    Hi,

    Yes, your observations are rigth. The internal DragDropManager looks for Mouse events on the root element of Visual Tree in which FlexGrid is contained. Also, adding the canvas to root Grid and then applying HitTest will produce incorrect results as now mouse positions are being calculated relative to root Grid instead of the Grid in which FlexGrid is present. So, I would suggest you to handle MouseMove and MouseUp events on the root grid and let the rest unchanged.

    Also, you can refer the modified attached sample (prj_DragDropEffect.zip). Hope this will help.

    Thanks and Regards,

    Basant

    prj_DragDropEffect.zip

  • Posted 19 December 2018, 6:49 am EST

    That does work, but when I extrapolate that to our application I’m still getting that pesky infinity at times. Worse, it seems to be somewhat intermittent.

    I’ll try to put together another test project that’s closer to our UI architecture and see if I can demonstrate what’s happening.

  • Posted 19 December 2018, 3:48 pm EST

    Hi,

    We are sorry for the inconvenience, I think the problem is happening because of our logic for finding mouse position. As we are finding mouse position relative to Canvas instead of FlexGrid, so can you please replace the calculation of position, hitTest and shiftPoint by the following:

    
    var position = Mouse.GetPosition(flexGrid);
    var hitTest = flexGrid.HitTest(position);
    var shiftPoint = new Point(position.X - hitTest.Rect.X - flexGrid.RowHeaders.ActualWidth, position.Y);
    
    

    This must resolve your problem of HitTest resulting in infinity.

    Thanks

  • Posted 20 December 2018, 6:16 am EST

    That totally fixed it, thank you very much!

Need extra support?

Upgrade your support plan and get personal unlimited phone support with our customer engagement team

Learn More

Forum Channels