0

我在数据网格中添加了拖放功能。但是,数据网格有一个嵌入的 DataGridComboBoxColumn,拖放功能会干扰该列。这是因为拖放处理程序无法识别用户拖放和用户从组合框列表中进行选择之间的区别(因此用户无法从列表中选择选项)。

我想在组合框 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);
}

谢谢

4

1 回答 1

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);
    }
于 2013-07-08T14:49:43.097 回答