views:

37

answers:

0

I have a listview object containing files in the program. The default listview behavior allows me to do all the select operations on the list (click+shift to select a block, click+ctrl for individually selecting members of a group of items, and click to select a single item).

I want to begin dragging these items with a click and hold of the left mouse button, but it deselects the items... and even as the mouse moves, it will select whatever the mouse is over. How do I handle the mouse events to allow default selection normally, but no select/deselect if the item is being dragged?

If I handle the down click event, the selection change happens at the same time... its only when a drag starts while the click is still down that I know that it is a drag and drop vs a selection change.

Here is the basic XAML for the control...

<Window.Resources>
    <Style x:Key="itemstyle" TargetType="{x:Type ListViewItem}">
        <EventSetter Event="PreviewMouseDown" Handler='listView2_MouseLeftButtonDown'/>
    </Style>
</Window.Resources>


<ListView Grid.Column="0" Grid.Row="1" Name="listView2" Margin="5,5,5,5" BorderBrush="LightGray" AllowDrop="True" Drop="listView2_Drop" ItemsSource="{Binding}" ItemContainerStyle="{StaticResource itemstyle}">
                <ListView.View>
                    <GridView>
                        <GridViewColumn Header="Name" Width="100">
                            <GridViewColumn.CellTemplate>
                                <DataTemplate>
                                    <StackPanel Orientation="Horizontal">
                                        <Image Source="{Binding Bmp}"/>
                                        <TextBlock Text="{Binding Name}"/>
                                    </StackPanel>
                                </DataTemplate>
                            </GridViewColumn.CellTemplate>
                        </GridViewColumn>
                        <GridViewColumn Header="Ext" DisplayMemberBinding="{Binding Ext}" Width="Auto"/>
                        <GridViewColumn Header="Size" DisplayMemberBinding="{Binding Size}" Width="Auto"/>
                        <GridViewColumn Header="Date" DisplayMemberBinding="{Binding Date}" Width="Auto"/>
                    </GridView>
                </ListView.View>
            </ListView>

Ok, so I've gone with handling the previewmousedown and preview mouse up events... if a control key or shift key is pressed, I don't set the handle flag... but otherwise I set the handled argument to true (so selection changes don't happen) Then on the previewmouseup event, I complete the single selection by setting the "selected" value to true (again only when shift or ctrl is pressed). So this kinda works... but the shift-block-selection doesn't use any item I select programatically as a valid starting point for the select, instead going to the first item clicked using a shift or ctrl key (even if I've cleared all the selected items manually).

Here is the source:

private void listView2_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (!Keyboard.IsKeyDown(Key.LeftCtrl) &&
               !Keyboard.IsKeyDown(Key.RightCtrl) &&
               !Keyboard.IsKeyDown(Key.LeftShift) &&
               !Keyboard.IsKeyDown(Key.RightShift))
            {
                e.Handled = true;
            }
        }
    }

    private void listView2_MouseLeftButtonUp(object sender, MouseButtonEventArgs e)
    {
        if (e.ChangedButton == MouseButton.Left)
        {
            if (!Keyboard.IsKeyDown(Key.LeftCtrl) &&
               !Keyboard.IsKeyDown(Key.RightCtrl) &&
               !Keyboard.IsKeyDown(Key.LeftShift) &&
               !Keyboard.IsKeyDown(Key.RightShift))
            {

                listView2.SelectedItems.Clear();
                ListViewItem lvi = sender as ListViewItem;
                listView2.SelectedItem = lvi;
                lvi.IsSelected = true;
                e.Handled = true;
            }
        }
    }