2010-07-16 71 views
5

我有一個listview對象包含程序中的文件。默認的列表視圖行爲允許我在列表上執行所有選擇操作(單擊+ shift選擇一個塊,單擊+ ctrl單獨選擇一組項目的成員,然後單擊選擇一個項目)。WPF listview drag without deselect

我想通過點擊並按住鼠標左鍵開始拖動這些項目,但它會取消選擇項目...並且即使隨着鼠標移動,它將選擇鼠標移動的任何內容。如何處理鼠標事件以正常進行默認選擇,但如果正在拖動項目,則不會選擇/取消選擇?

如果我處理向下單擊事件,選擇更改同時發生......只有在點擊仍然停止時發生拖動,我知道它是拖放與選擇更改。

下面是控制基本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> 

好了,我已經與處理previewmousedown和預覽鼠標向上事件......如果控制鍵或Shift按下鍵,我不設置句柄標誌...但除此之外,我將處理的參數設置爲true(所以不會發生選擇更改)。然後在previewmouseup事件中,通過設置「選定」值設置爲真(再次僅在按下shift或ctrl時)。所以這種方法可行......但是shift-block-selection不使用我選擇的任何項目作爲select的有效起點,而是使用shift或ctrl鍵點擊第一個項目(即使我選擇了「已經手動清除了所有選定的項目)。

這裏是源:

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

回答

0

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


The IListItem接口是我的數據對象實現的接口,以便在我的TreeView中顯示。 ViewModel屬性是我的看法DataContext。 此外,以下評論非常重要:「TreeViewItem從未真正被選中......選中時,我們手動更改其背景顏色(請參閱xaml)」。

所以基本上,我所做的是從TreeView控件中刪除選擇處理來自己處理它。

希望這有助於任何方式...