The problem:
My application requires a user to be able to select multiple entries in a datagrid via a column of checkboxes. The desired behavior is that when you click on a checkbox in the column, it behaves like a normal checkbox, but if you drag over it while the left mouse button is down, its selection state changes to the opposite of what is was before.
What I have tried so far:
I have tried subclassing CheckBox and handling OnMouseEnter, but the first checkbox that is clicked seems to capture the mouse so no other checkboxes fire the OnMouseEnter event.
I have tried implementing a drag-and-drop hack, where the user clicks to select a checkbox, and then drags that checkbox over the others so the others recieve a DragOver event and can switch states. This solution causes the cursor to display as a circle with a slash when not over another checkbox during the drag and drop, which is not acceptable for this application.
What I would like:
I would like a method to implement a checkbox that has the functionality I describe, ideally in a xaml style or subclass that I can reuse, as this functionality is needed in multiple places in my application.
Is there an elegant way to achieve this effect?
I did this in my application, very handy when you have to select, say, 30 checkBoxes.
To do this, i handled the preview mouse event myself : PreviewMouseLeftButtonDown, PreviewMouseMove, PreviewMouseLeftButtonUp.
In PreviewMouseLeftButtonDown : i get the mouse position relative to the control.
In PreviewMouseMove : i draw a rectangle from start to current position if i am far enough from firstPoint. then i iterate in CheckBoxes, see if they intersect with rectangle, and highlight them if so (so the user know whiwh chexboxes will swap)
In PreviewMouseLeftButtonUp : i do the swap for intersecting CheckBoxes.
if it can help you, here’s the code i use. it is not MVVM (:-)) but works fine, it might give you ideas. it is an automatic translation from vb.net code.
To make it work, you need a Canvas on top of your CheckBoxes (=within the same grid cell for instance), with property IsHitTestVisible=”False” .
Within this Canvas, put a Rectangle nammed “SelectionRectangle” with proper fill and stroke, but with 0.0 Opacity.
Edit : i used that code within a user control. This control takes a list of booleans and a list of strings (caption) as argument, and builds (with a WrapPanel) an array of CheckBoxes having the right caption. And so you can select/unselect with the rectangle, and there are also two buttons to check all/uncheck all. I tried also to keep good column/rows ratio to handle selection of 7 to 200 booleans with a good column/row balance.