WPF确定何时删除数据网格的DataGridComboBoxColumn列表

时间:2013-07-08 14:09:47

标签: c# wpf datagrid datagridcomboboxcolumn

我在数据网格中添加了拖放功能。但是,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);
}

由于

1 个答案:

答案 0 :(得分: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);
    }