代码之家  ›  专栏  ›  技术社区  ›  tbischel

WPF listview拖动而不取消选择

  •  5
  • tbischel  · 技术社区  · 16 年前

    我有一个listview对象,其中包含程序中的文件。默认的listview行为允许我执行列表上的所有选择操作(单击+shift选择块,单击+ctrl分别选择一组项目的成员,单击选择单个项目)。

    我想通过点击并按住鼠标左键开始拖动这些项目,但它会取消选择这些项目。。。即使在鼠标移动的时候,它也会选择鼠标所在的位置。如何处理鼠标事件以允许正常默认选择,但如果拖动项目,则不允许选择/取消选择?

    如果我处理向下单击事件,选择更改将同时发生。。。只有当鼠标点击时开始拖动,我才知道这是拖放而不是选择的改变。

    下面是控件的基本XAML。。。

    <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>
    

    资料来源如下:

    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;
                }
            }
        }
    
    1 回复  |  直到 16 年前
        1
  •  1
  •   Devendra D. Chavan    15 年前

    我和他有同样的问题 TreeView 不久前的控制。。。以下是我如何解决这个问题的:

    private void TreeViewItem_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e)
    {
        // skip mouse clicks on the expander button
        if (e.Source is ToggleButton)
            return;
    
        // find the original source's parent TreeViewItem
        DependencyObject originalSource = e.OriginalSource as DependencyObject;
        while (originalSource != null)
        {
            TreeViewItem tvi = originalSource as TreeViewItem;
            if (tvi != null)
            {
                IListItem listItem = tvi.Header as IListItem;
                if (listItem != null)
                {
                    if (Keyboard.Modifiers == ModifierKeys.Shift)
                        ViewModel.MultiSelectTo(listItem);
                    else if (Keyboard.Modifiers == ModifierKeys.Control)
                        ViewModel.ToggleSelection(listItem);
                    else
                        ViewModel.Select(listItem);
                }
    
                // the TreeViewItem is never truly selected... when selected, we manually change it's background color (see xaml)
                tvi.IsSelected = false;
                e.Handled = true;
                break;
            }
    
            originalSource = VisualTreeHelper.GetParent(originalSource);
        }
    }
    

    XAML:

    <Style.Triggers>
    <DataTrigger Binding="{Binding Selected}" Value="True">
        <Setter Property="Background" Value="#FF3399FF" />
    </DataTrigger>
    </Style.Triggers>
    


    IListItem 接口是我的数据对象实现的接口,以便显示在我的 . ViewModel 财产是我的观点 DataContext

    树景 控制自己来处理它。

    推荐文章