2013-07-08 31 views
0

我已經添加了一個拖放功能到數據網格。但是,datagrid具有拖放功能干擾的嵌入式DataGridComboBoxColumn。這是因爲拖放處理程序不能識別用戶拖放操作和用戶從組合框列表中進行選擇(因此用戶無法從列表中選擇一個選項)之間的區別。WPF識別DataGrid的DataGridComboBoxColumn列表何時被刪除

我想要斷開拖放事件,而combox isDropDownOpen布爾值設置爲true或在拖放處理程序中折扣此操作。然而,我不知道如何做到這一點,因爲我只是不知道如何確定何時擴展組合框。

我的數據網格的代碼如下(XAML):

<DataGrid x:Name="dgdNoteLimits" 
       Grid.Row="1" 
       AllowDrop="True" 
       AutoGenerateColumns="False" 
       Background="{DynamicResource myPanelColor}" 
       BorderThickness="0" 
       CanUserReorderColumns="False" 
       CanUserSortColumns="False" 
       ColumnHeaderStyle="{StaticResource headerText}" 
       CurrentCellChanged="dgdNoteLimits_CurrentCellChanged" 
       HeadersVisibility="Column" 
       HorizontalGridLinesBrush="DarkGray" 
       ItemsSource="{Binding TargetPoints}" 
       RowBackground="{DynamicResource myBackgroundColor}" 
       VerticalGridLinesBrush="DarkGray"> 
     <DataGrid.ItemContainerStyle> 
       <Style> 
        <Style.Resources> 
         <!-- SelectedItem's background color when focused --> 
         <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" 
             Color="Blue"/> 
         <!-- SelectedItem's background color when NOT focused --> 
         <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" 
             Color="Blue" /> 
        </Style.Resources> 
       </Style> 
      </DataGrid.ItemContainerStyle> 
      <DataGrid.Columns> 
      <DataGridComboBoxColumn x:Name = "dgComboBox" 
            Header = "Paragraph Type" 
            ItemsSource = "{Binding Source={StaticResource ParaType}}" 
            SelectedValueBinding = "{Binding Path=ParagraphType, UpdateSourceTrigger=PropertyChanged}" 
            TextBinding = "{Binding Path=ParagraphType}" 
            MinWidth = "115" 
            Width = "Auto"> 
       <DataGridComboBoxColumn.ElementStyle> 
        <Style TargetType = "ComboBox"> 
         <Setter Property = "Foreground" 
           Value = "{DynamicResource TextColor}"/> 
         <EventSetter Event="SelectionChanged" 
            Handler = "OnDropDownOpenedEvent" /> 
        </Style> 
       </DataGridComboBoxColumn.ElementStyle> 
      </DataGridComboBoxColumn> 
      <DataGridTextColumn x:Name="dgdTextColumn" 
           Header="Description" 
           Binding="{Binding Path=ParagraphText, UpdateSourceTrigger=PropertyChanged}" 
           Width="*"> 
       <DataGridTextColumn.ElementStyle> 
        <Style x:Name="myStyle" 
          TargetType="TextBlock"> 
         <Setter Property="SpellCheck.IsEnabled" 
           Value="true" /> 
         <Setter Property="TextWrapping" 
           Value="Wrap"/> 
         <Setter Property="Foreground" 
           Value="{DynamicResource myTextColor}"/> 
        </Style> 
       </DataGridTextColumn.ElementStyle> 
      </DataGridTextColumn> 
      </DataGrid.Columns> 
     </DataGrid> 

我的代碼的一個子集,後面如下:

private bool IsTheMouseOnTargetRow(Visual theTarget, GetDragDropPosition pos) 
{ 
    if (theTarget != null) 
    { 
     Rect posBounds = VisualTreeHelper.GetDescendantBounds(theTarget); 
     Point theMousePos = pos((IInputElement)theTarget); 
     return posBounds.Contains(theMousePos); 
    } 
    else 
     return false; 
} 

private DataGridRow GetDataGridRowItem(int index) 
{ 
    if (dgdNoteLimits.ItemContainerGenerator.Status != System.Windows.Controls.Primitives.GeneratorStatus.ContainersGenerated) 
     return null; 

    return dgdNoteLimits.ItemContainerGenerator.ContainerFromIndex(index) as DataGridRow; 
} 

private int GetDataGridItemCurrentRowIndex(GetDragDropPosition pos) 
{ 
    int curIndex = -1; 
    DataGridRow itm; 

    for (int i = 0; i < dgdNoteLimits.Items.Count; i++) 
    { 
     itm = GetDataGridRowItem(i); 
     if (IsTheMouseOnTargetRow(itm, pos)) 
     { 
      curIndex = i; 
      break; 
     } 
    } 

    return curIndex; 
} 

void dgdNoteLimits_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
{ 
    prevRowIndex = GetDataGridItemCurrentRowIndex(e.GetPosition); 

    if (prevRowIndex < 0) 
     return; 

    dgdNoteLimits.SelectedIndex = prevRowIndex; 

    INote selectedNote = dgdNoteLimits.Items[prevRowIndex] as INote; 

    if (selectedNote == null) 
     return; 

    if (isDroppedDown) 
     return; 

    //Now creare a Drop rectangle with Mouse Drag-Effect 
    //Here you can select the Effect as per your choice 
    DragDropEffects dragDropEffects = DragDropEffects.Move; 

    if (DragDrop.DoDragDrop(dgdNoteLimits, selectedNote, dragDropEffects) != DragDropEffects.None) 
    { 
     //This Item is dropped at the new datagrid location and so the new selected item 
     dgdNoteLimits.SelectedItem = selectedNote; 
    } 
} 

void dgdNoteLimits_Drop(object sender, DragEventArgs e) 
{ 
    if (prevRowIndex < 0) 
     return; 

    int index = this.GetDataGridItemCurrentRowIndex(e.GetPosition); 

    //The current Rowindex is -1 (No selection) 
    if (index < 0) 
     return; 

    //If Drag-Drop Location are same. 
    if (index == prevRowIndex) 
     return; 

    /* NOT REQUIRED AS LAST ROW IS NOT FOR INSERTIONS 
    // If the drop index is the last Row of datagrid 
    // (Note: This row is typically used for performing insert operations) 
    if (index == dgdNoteLimits.Items.Count - 1) 
    { 
     MessageBox.Show("You cannot use this row-index for drop operations"); 
     return; 
    }*/ 

    INote movedNote = Paragraphs[prevRowIndex]; 
    Paragraphs.RemoveAt(prevRowIndex); 
    Paragraphs.Insert(index, movedNote); 
} 

感謝

回答

0

開始之前的拖放操作你可以檢查一下,確保它不是像這樣的組合框。

protected override void OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e) 
    { 
     DependencyObject source = e.OriginalSource as DependencyObject; 
     while (source != null && !(source is System.Windows.Controls.ComboBox)) source = VisualTreeHelper.GetParent(source); 
     if (source != null) 
     { 
      // it was a combo box, don't start drag drop. 
     } 
     else 
     { 
      // it wasn't a combo box do drag drop. 
     } 


     base.OnPreviewMouseLeftButtonDown(e); 
    } 
+0

非常感謝安迪。你在現場。 – greenbeast