2017-06-02 356 views
0

因此,我已經非常遵循每個示例我可以找到關於如何將WPF控件上的拖放效果設置爲無以線圈符號顯示圓形,但無濟於事。WPF拖放沒有效果沒有觸發

這是我從各種例子複製的代碼,修改它來得到它的工作:

這是代碼後面的窗口:

using System; 
    using System.Windows; 
    using System.Windows.Controls; 
    using System.Windows.Input; 

    namespace TreeViewWithCheckBoxes 
    { 
     public partial class Window1 : Window 
     { 
      public Window1() 
      { 
       InitializeComponent(); 

       FooViewModel root = this.tree.Items[0] as FooViewModel; 

       base.CommandBindings.Add(
       new CommandBinding(
        ApplicationCommands.Undo, 
        (sender, e) => // Execute 
        {       
         e.Handled = true; 
         root.IsChecked = false; 
         this.tree.Focus(); 
        }, 
        (sender, e) => // CanExecute 
        { 
         e.Handled = true; 
         e.CanExecute = (root.IsChecked != false); 
        })); 

       this.tree.Focus(); 
      } 

      private void TreeViewItemDragEnter(object sender, DragEventArgs e) 
      { 
       e.Effects = DragDropEffects.None; 
       if (e.Data.GetDataPresent(typeof(FooViewModel))) 
       { 
        var folderViewModel = e.Data.GetData(typeof(FooViewModel)) 
         as FooViewModel; 
        var treeViewItem = 
         VisualTreeHelperUtils.FindParent<TreeViewItem> 
         ((DependencyObject)e.OriginalSource); 

        if (treeViewItem == null) 
        { 
         return; 
        } 
        var dropTarget = treeViewItem.Header as FooViewModel; 

        if (dropTarget == null || folderViewModel == null) 
        { 
         return; 
        } 

        if (dropTarget.Parent == folderViewModel.Parent) 
         e.Effects = e.AllowedEffects; 
        else 
        { 
         e.Effects = DragDropEffects.None; 
        } 
       } 
      } 

      private void TreeViewItemDrop(object sender, DragEventArgs e) 
      { 
       if (e.Data.GetDataPresent(typeof(FooViewModel))) 
       { 
        var folderViewModel = e.Data.GetData(typeof(FooViewModel)) 
         as FooViewModel; 
        var treeViewItem = 
         VisualTreeHelperUtils.FindParent<TreeViewItem> 
         ((DependencyObject)e.OriginalSource); 

        var dropTarget = treeViewItem.Header as FooViewModel; 

        if (dropTarget == null || folderViewModel == null) 
         return; 

        if (dropTarget.Parent == folderViewModel.Parent) 
        { 
         var dropType = dropTarget.Name; 
         var dragType = folderViewModel.Name; 

         var parent = dropTarget.Parent; 

        if (parent != null) 
        { 
         var dropLocation = -1; 
         var dragLocation = -1; 
         for (int index = 0; index < parent.Children.Count; ++index) 
         { 
          if (parent.Children[index].Name == dropType) dropLocation = index; 
          if (parent.Children[index].Name == dragType) dragLocation = index; 
          if (dropLocation != -1 && dragLocation != -1) 
           break; 
         } 

         if (dropLocation != -1 && dragLocation != -1) 
         { 
          parent.Children[dropLocation] = folderViewModel; 
          parent.Children[dragLocation] = dropTarget; 
         } 
        } 
       } 
      } 
     } 

     private void TreeViewItemMouseMove(object sender, MouseEventArgs e) 
     { 
      if (e.LeftButton == MouseButtonState.Pressed) 
      { 
       var mousePos = e.GetPosition(null); 
       var diff = StartPoint - mousePos; 

       if (Math.Abs(diff.X) > SystemParameters.MinimumHorizontalDragDistance 
        || Math.Abs(diff.Y) > SystemParameters.MinimumVerticalDragDistance) 
       { 
        var treeView = sender as TreeView; 
        var treeViewItem = 
         VisualTreeHelperUtils.FindParent<TreeViewItem>((DependencyObject)e.OriginalSource); 

        if (treeView == null || treeViewItem == null) 
         return; 

        var folderViewModel = treeView.SelectedItem as FooViewModel; 
        if (folderViewModel == null) 
         return; 

        var dragData = new DataObject(folderViewModel); 
        DragDrop.DoDragDrop(treeViewItem, dragData, DragDropEffects.Move); 
       } 
      } 
     } 

     private void TreeViewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
     { 
      StartPoint = e.GetPosition(null); 
     } 

     public Point StartPoint { get; set; } 

     private void TreeViewItemDragOver(object sender, DragEventArgs e) 
     { 
      var container = sender as FrameworkElement; 

      if (container == null) 
      { 
       return; 
      } 

      var scrollViewer = VisualTreeHelperUtils.GetFirstVisualChild<ScrollViewer>(container); 

      if (scrollViewer == null) 
      { 
       return; 
      } 

      double tolerance = 30; 
      double verticalPos = e.GetPosition(container).Y; 
      double offset = 20; 

      if (verticalPos < tolerance) // Top of visible list? 
      { 
       scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset - offset); //Scroll up. 
      } 
      else if (verticalPos > container.ActualHeight - tolerance) //Bottom of visible list? 
      { 
       scrollViewer.ScrollToVerticalOffset(scrollViewer.VerticalOffset + offset); //Scroll down.  
      } 

      e.Effects = DragDropEffects.None; 

      var source = e.OriginalSource as DependencyObject; 

      if (source == null) 
      { 
       return; 
      } 
      if (e.Data.GetDataPresent(typeof(FooViewModel))) 
      { 
       var folderViewModel = e.Data.GetData(typeof(FooViewModel)) 
        as FooViewModel; 
       var treeViewItem = 
        VisualTreeHelperUtils.FindParent<TreeViewItem>((DependencyObject)e.OriginalSource); 

       if (treeViewItem == null) 
       { 
        return; 
       } 
       var dropTarget = treeViewItem.Header as FooViewModel; 

       if (dropTarget == null || folderViewModel == null) 
       { 
        return; 
       } 

       if (dropTarget.Parent == folderViewModel.Parent) 
        e.Effects = e.AllowedEffects; 
       else 
       { 
        e.Effects = DragDropEffects.None; 
       } 
      } 
     } 
    } 
} 

這裏是XAML吧,這表明它已經註冊到正確的事件:

<Window 
    x:Class="TreeViewWithCheckBoxes.Window1" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:TreeViewWithCheckBoxes" 
    xmlns:dw="clr-namespace:DrWPF.Windows.Controls" 
    FontSize="13" 
    Title="TreeView with CheckBoxes" 
    Width="300" Height="300" 
    WindowStartupLocation="CenterScreen" 
    > 
    <Window.Resources> 
    <ResourceDictionary> 
     <!-- Load this specific theme because the Aero theme for CheckBox has issues. --> 
     <ResourceDictionary.MergedDictionaries> 
     <ResourceDictionary Source="/PresentationFramework.Royale;V3.0.0.0;31bf3856ad364e35;component\themes\royale.normalcolor.xaml" /> 
     </ResourceDictionary.MergedDictionaries> 

     <Style x:Key="TreeViewItemStyle" TargetType="TreeViewItem"> 
     <Setter Property="IsExpanded" Value="True" /> 
     <Setter Property="IsSelected" Value="{Binding IsInitiallySelected, Mode=OneTime}" /> 
     <Setter Property="KeyboardNavigation.AcceptsReturn" Value="True" /> 
     <Setter Property="dw:VirtualToggleButton.IsVirtualToggleButton" Value="True" /> 
     <Setter Property="dw:VirtualToggleButton.IsChecked" Value="{Binding IsChecked}" />   
     </Style> 

     <HierarchicalDataTemplate 
     x:Key="CheckBoxItemTemplate" 
     ItemsSource="{Binding Children, Mode=OneTime}" 
     > 
     <StackPanel Orientation="Horizontal"> 
      <!-- These elements are bound to a FooViewModel object. --> 
      <CheckBox 
      Focusable="False" 
      IsChecked="{Binding IsChecked}" 
      VerticalAlignment="Center" 
      /> 
      <ContentPresenter 
      Content="{Binding Name, Mode=OneTime}" 
      Margin="2,0" 
      /> 
     </StackPanel> 
     </HierarchicalDataTemplate> 
    </ResourceDictionary> 
    </Window.Resources> 

    <Window.DataContext> 
    <ObjectDataProvider 
     MethodName="CreateFoos" 
     ObjectType="{x:Type local:FooViewModel}" /> 
    </Window.DataContext> 

    <TabControl> 
     <TabItem Header="Original"> 
      <Grid> 
       <Grid.RowDefinitions> 
        <RowDefinition Height="3*"/> 
        <RowDefinition Height=".2*"/> 
        <RowDefinition Height="2*"/> 
        <RowDefinition Height="*"/> 
       </Grid.RowDefinitions> 
       <Button 
       Grid.Row="3" 
       Command="Undo" 
       Content="Generate Report" 
       HorizontalAlignment="Center" 
       Margin="0,2" 
       Padding="8,0" 
       /> 
       <TreeView 
        Grid.Row="0" 
       x:Name="tree" 
       ItemContainerStyle="{StaticResource TreeViewItemStyle}" 
       ItemsSource="{Binding Mode=OneTime}" 
       ItemTemplate="{StaticResource CheckBoxItemTemplate}" 
        AllowDrop="True" 
       PreviewMouseLeftButtonDown="TreeViewMouseLeftButtonDown" 
       PreviewMouseMove="TreeViewItemMouseMove" 
       DragEnter="TreeViewItemDragEnter" 
       DragOver="TreeViewItemDragOver" 
       Drop="TreeViewItemDrop" 
       /> 
       <ScrollViewer Grid.Row="2" IsEnabled="{Binding ElementName=tree, Path=SelectedItem.IsChecked}"> 
        <TextBlock Text="Oh Hai"></TextBlock> 
        <ScrollViewer.Style> 
         <Style TargetType="ScrollViewer"> 
          <Style.Triggers> 
           <Trigger Property="IsEnabled" Value="False"> 
            <Setter Property="Opacity" Value="0.5"></Setter> 
            <Setter Property="VerticalScrollBarVisibility" Value="Hidden"></Setter> 
           </Trigger> 
           <Trigger Property="IsEnabled" Value="True"> 
            <Setter Property="Opacity" Value="1"></Setter> 
            <Setter Property="VerticalScrollBarVisibility" Value="Auto"></Setter> 
           </Trigger> 
          </Style.Triggers> 
         </Style> 
        </ScrollViewer.Style> 
       </ScrollViewer> 
      </Grid> 
     </TabItem> 
     <TabItem Header="Modified"> 
      <DockPanel> 
       <Button 
       DockPanel.Dock="Bottom" 
       Command="Undo" 
       Content="Uncheck All" 
       HorizontalAlignment="Center" 
       Margin="0,2" 
       Padding="8,0" 
       /> 
       <TreeView 
       x:Name="modified" 
       ItemContainerStyle="{StaticResource TreeViewItemStyle}" 
       ItemsSource="{Binding Mode=OneTime}" 
       ItemTemplate="{StaticResource CheckBoxItemTemplate}" 
       /> 
      </DockPanel> 
     </TabItem> 
    </TabControl> 

</Window> 

我沒有附加任何代碼的輔助方法......這些都做工精細,並且向上滾動的基本思想/向下而拖動和交換塊內的項目工作都很好。

但是,愚蠢的圖標拒絕爲我改變。 :)

我甚至試圖將它設置爲處理程序的最頂部無,並只設置它回到AllowedEffects如果父母是相同的。

從本質上講,圖標應該通過它(無)切換到與線的圓圈,如果拖曳到父母那是不一樣的......

我甚設置斷點,以確保其進入父母的情況並不相同,並將效果設置爲無。不知怎的,一些東西必須切換回來,但我不知道什麼...

+0

因此,我甚至只是簡單地將e.Effects = DragDropEffects.None設置爲DragOver和DragEnter事件處理程序中的唯一事物,並且它仍然不會更改圖標。我什至嘗試預覽事件處理程序而不是隧道事件處理程序,並且它也不起作用。然後我也試着讓這兩個版本的事件處理程序不做任何事情,但是設置e.Effects = DragDropEffects.None,並且圖標不會改變...... – cwodarczyk82

回答

0

顯然,你也必須在設置e.Effects後在處理程序中設置e.Handled = true。這樣做後,它完美的作品。