This is a migrated thread and some comments may be shown as answers.

Multi-select using Shift+Click

6 Answers 712 Views
Diagram
This is a migrated thread and some comments may be shown as answers.
Peter
Top achievements
Rank 1
Peter asked on 03 Mar 2014, 09:07 PM
Hello,

I would like to add support to my RadDiagram for the user to perform a multi-select operation using the Shift key, in addition to the default Ctrl key.  I looked at adding to the InputBindings but there is no Command for select.  I also tried adding a handler for OnSelectionChanged that attempted to re-select the items in the SelectionChangedEventArgs.RemovedItems but my changes were apparently overridden after the handler completed and only the last clicked item would be selected.

Is there a way to implement this?

Thanks,

Peter Pepperell

6 Answers, 1 is accepted

Sort by
0
Martin Ivanov
Telerik team
answered on 06 Mar 2014, 04:46 PM
Hello Peter,

As RadDiagram doesn't support this functionality out-of-the-box you can achieve your requirements with custom logic. You can handle the KeyDown, SelectionChanged and PreviewSelectionChanged events of the diagram.

In the KeyDown handler you will need to check if the Shift and the left mouse button are down. If so, you can use the Diagram HitTestService to select the shape which is under the mouse and then select it with the SelectionService.SelectItem() method. Note that the second parameter of the SelectedItem() method controls if the item should be added in the current selected items collection. You can read more about the Diagram Services in our help.
private HitTestService hitTestService;
private SelectionService selectionService;
 
public MainWindow()
{
    InitializeComponent();
 
    this.AddHandler(RadDiagram.KeyDownEvent, new KeyEventHandler(OnKeyDown), true);
 
    hitTestService = this.diagram.ServiceLocator.GetService<IHitTestService>() as HitTestService;
    selectionService = this.diagram.ServiceLocator.GetService<ISelectionService<IDiagramItem>>() as SelectionService;
}
private void OnKeyDown(object sender, KeyEventArgs args)
{
    bool isShiftKeyDown = (args.Key == Key.LeftShift || args.Key == Key.RightShift);
    bool isLeftMouseButtonDown = Mouse.LeftButton == MouseButtonState.Pressed;
 
    if (isShiftKeyDown && isLeftMouseButtonDown )
    {
        this.selectionService.SelectItem(this.hitTestService.ItemUnderMouse, true);
    }
}

The logic in the Diagram.PreviewSelectionChanged checks if the Shift key is down and if there are any items in the RemovedItems collection. If so, handle the event with e.Handled = true.
private void diagram_PreviewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    bool isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
    if (isShiftKeyDown && e.RemovedItems.Count != 0)
        e.Handled = true;
}
 In the SelectionChanged  handle we get all shapes under the selection rectangle and select them one by one. This logic demonstrates how to select all the items in the selection rectangle bounds. But if you want to select only the clicked items you don't have to use it.

private void diagram_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    bool isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
    if (isShiftKeyDown)
    {
        var shapes = hitTestService.GetShapesUnderRect(diagram.SelectionBounds);
 
        foreach (RadDiagramShape shape in shapes)
        {
            shape.IsSelected = true;
        }
    }
}

I attached a sample project with this implementation which you can use as a base for your requirements.

Regards,
Martin
Telerik

DevCraft Q1'14 is here! Join the free online conference to see how this release solves your top-5 .NET challenges. Reserve your seat now!

0
Peter
Top achievements
Rank 1
answered on 07 Mar 2014, 07:48 PM
Hi Martin,

Thanks for the sample code, it works for my needs, but only to a point.  I want the Shift key to have the same behavior as the Ctrl key does, including deselecting individual items (when already selected) but leaving the remaining selected items unchanged.

I made some changes to the sample you sent, but I was unable to achieve the desired result.  

Can you show me what changes need to be made to your previous sample code to make the Shift+Click key combo mimic the behavior of the Ctrl+Click?

Thanks,

Peter
0
Martin Ivanov
Telerik team
answered on 12 Mar 2014, 04:08 PM
Hi Peter,

In order to add this functionality you will need to do few changes in the last project that I send you. It seems that the KeyDown event is called too early that's why we should move our selection/deselection logic in the Diagram ShapeClick event handler and then made some changes. Here is an example in code:
private void diagram_ShapeClicked(object sender, Telerik.Windows.Controls.Diagrams.ShapeRoutedEventArgs e)
{
    bool isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
    if (isShiftKeyDown)
    {
        toolService.DeactivateTool(toolService.ToolList[0]);
        if (e.Shape.IsSelected)
        {
            this.selectionService.DeselectItem(e.Shape);
        }
        else
        {
            this.selectionService.SelectItem(e.Shape, true);
        }
    }
}
 
private void diagram_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
{
    toolService.ActivateTool((toolService.ToolList[0] as ToolBase).Name);
}

Note that we are deactivating the PointerTool from the tools of the ToolService. Otherwise the selection will be triggered twice. Once for our custom selection and second time for the default selection. The PointerTool controls how the selection in the Diagram should be handled. After our custom selection we should activate this tool again in order for the default selection to work correctly. You can read more about the tools in the Tools Customization help article.

I also attached an updated project with this implementation. I hope this is helpful. 

Regards,
Martin
Telerik
 

DevCraft Q1'14 is here! Watch the online conference to see how this release solves your top-5 .NET challenges. Watch on demand now.

 
0
Douwe
Top achievements
Rank 1
answered on 14 Oct 2016, 07:22 AM
I am also very interested in this functionality but unfortunately the attached sample project cannot be downloaded anymore; could this link be fixed?
0
Douwe
Top achievements
Rank 1
answered on 14 Oct 2016, 11:02 AM

Ok, I played around with the sample code above and came up with the following changes which seem to work just fine. The only thing which bothers me is that I made less changes then described above so I'm wondering if there are scenarios where my code will not work or have undesired side effects?

In the previewSelectionChanged event handler I added an additional condition for the e.Handled to be set to True and this was needed to get the 'deselect' to work (when pressing the Shift key and clicking on a selected shape). 

 

DiagramControl.PreviewSelectionChanged += DiagramControl_PreviewSelectionChanged;
DiagramControl.ShapeClicked += DiagramControl_ShapeClicked;
 
m_diagramSelectionService = DiagramControl.ServiceLocator.GetService<ISelectionService<IDiagramItem>>() as SelectionService;
 
void DiagramControl_ShapeClicked(object sender, ShapeRoutedEventArgs e)
{
    bool isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
 
    if (isShiftKeyDown)
    {
        if (e.Shape.IsSelected)
        {
            m_diagramSelectionService.DeselectItem(e.Shape);
        }
        else
        {
            m_diagramSelectionService.SelectItem(e.Shape, true);
        }
    }
}
 
void DiagramControl_PreviewSelectionChanged(object sender, SelectionChangedEventArgs e)
{
    bool isShiftKeyDown = Keyboard.IsKeyDown(Key.LeftShift) || Keyboard.IsKeyDown(Key.RightShift);
 
    if (isShiftKeyDown && e.RemovedItems.Count != 0 && e.AddedItems.Count != 0)
    {
        e.Handled = true;
    }
}
0
Martin Ivanov
Telerik team
answered on 18 Oct 2016, 09:43 AM
Hello Douwe,

We had a technical issue with the attachments in the forum. The issue is already fixed so you should be able to download the .zip with the project. 

About your implementation, well at first sight I cannot tell if you are going to experience any undesired effects. But as this is a custom solution I won't be surprised if it happens. This is why I recommend you test all expected scenarios.

Regards,
Martin
Telerik by Progress
Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
Tags
Diagram
Asked by
Peter
Top achievements
Rank 1
Answers by
Martin Ivanov
Telerik team
Peter
Top achievements
Rank 1
Douwe
Top achievements
Rank 1
Share this question
or