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