2015-04-03 68 views
0

我有一個包含每個tabItem的Datagrid的TabControl的UserControl。 Datagrid有3列,其中一列作爲組合框列。如果使用拖放操作,WPF DataGridComboboxColumn選擇失敗

<UserControl x:Name="ConfigurationView" 
     x:Class="HyperPostHelper.Controls.ConfigurationControl" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:viewModel="clr-namespace:HyperPostHelper.ViewModel" 
     mc:Ignorable="d" 
     d:DesignHeight="300" d:DesignWidth="300" 
     ClipToBounds="True" 
     HorizontalAlignment="Stretch" VerticalAlignment="Stretch" 
     Width="auto" Height="auto" 
     Margin="5"> 
<Grid> 
    <TabControl x:Name="ConfigurationTab" ItemsSource="{Binding Path=ConfigurationFiles, UpdateSourceTrigger=PropertyChanged}"> 
     <TabControl.ItemTemplate> 
      <DataTemplate> 
       <TextBlock FontWeight="Bold" Text="{Binding FileName, UpdateSourceTrigger=PropertyChanged}" /> 
      </DataTemplate> 
     </TabControl.ItemTemplate> 
     <TabControl.ContentTemplate> 
      <DataTemplate> 
       <Grid> 
        <Grid.RowDefinitions> 
         <RowDefinition Height="30" /> 
         <RowDefinition Height="*" /> 
         <RowDefinition Height="30" /> 
        </Grid.RowDefinitions> 



        <DataGrid Name="ConfigurationFileView" 
           Grid.Row="1" 
           Margin="2" 
           AutoGenerateColumns="False" 
           ItemsSource="{Binding Parameters, 
                UpdateSourceTrigger=PropertyChanged}" 
           SelectedItem="{Binding SelectedItem, 
                UpdateSourceTrigger=PropertyChanged}" 
           AllowDrop="True" PreviewMouseLeftButtonDown="ConfigurationFileView_PreviewMouseLeftButtonDown" 
           Drop="ConfigurationFileView_Drop"> 
         <DataGrid.RowStyle> 
          <Style TargetType="DataGridRow"> 
           <Style.Triggers> 
            <DataTrigger Binding="{Binding IsValid, UpdateSourceTrigger=PropertyChanged}" Value="true"> 
             <Setter Property="Background" Value="White" /> 
            </DataTrigger> 
            <DataTrigger Binding="{Binding IsValid, UpdateSourceTrigger=PropertyChanged}" Value="false"> 
             <Setter Property="Background" Value="Red" /> 
            </DataTrigger> 
           </Style.Triggers> 
          </Style> 
         </DataGrid.RowStyle> 
         <DataGrid.Columns> 
          <DataGridTextColumn Binding="{Binding Name, UpdateSourceTrigger=PropertyChanged}" Header="Name" /> 
          <DataGridComboBoxColumn SelectedItemBinding="{Binding Path=Type, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Type"> 
           <DataGridComboBoxColumn.ElementStyle> 
            <Style TargetType="ComboBox"> 
             <Setter Property="ItemsSource" Value="{Binding ElementName=ConfigurationView, Path=DataContext.Types}" /> 
            </Style> 
           </DataGridComboBoxColumn.ElementStyle> 
           <DataGridComboBoxColumn.EditingElementStyle> 
            <Style TargetType="ComboBox"> 
             <Setter Property="ItemsSource" Value="{Binding ElementName=ConfigurationView, Path=DataContext.Types}" /> 
            </Style> 
           </DataGridComboBoxColumn.EditingElementStyle> 
          </DataGridComboBoxColumn> 
          <DataGridTextColumn Binding="{Binding Value, UpdateSourceTrigger=PropertyChanged}" Header="Value" Width="*" /> 
         </DataGrid.Columns> 
        </DataGrid> 
        <Grid Grid.Row="2"> 
         <Grid.ColumnDefinitions> 
          <ColumnDefinition Width="30" /> 
          <ColumnDefinition Width="30" /> 
          <ColumnDefinition Width="auto" /> 
         </Grid.ColumnDefinitions> 
         <Button Name="AddParameter" 
           Grid.Row="2" Grid.Column="0" 
           Margin="2" 
           Command="{Binding Path=AddParameterCommand}" 
           Style="{DynamicResource FlatButtonStyle}"> 
          <Button.ToolTip> 
           <TextBlock>Adds a new parametert to the selected list</TextBlock> 
          </Button.ToolTip> 
          <Grid> 
           <Image Width="20" Height="20" Source="..\Resources\Property-Add.png" /> 
          </Grid> 
         </Button> 
         <!--<Button Name="DeleteParameter" Grid.Row="2" Grid.Column="1" Margin="2" Command="{Binding Path=DeleteParameterCommand}" Style="{DynamicResource FlatButtonStyle}"> 
         <Button.ToolTip> 
          <TextBlock>Deletes a selected parameter from the selected list</TextBlock> 
         </Button.ToolTip> 
         <Grid> 
          <Image Width="20" Height="20" Source="..\Resources\Property-Delete.png" /> 
         </Grid> 
        </Button>--> 
        </Grid> 

       </Grid> 
      </DataTemplate> 

     </TabControl.ContentTemplate> 
    </TabControl> 
</Grid> 

現在我已經實現了一些將&刪除功能用於移動使用的PreviewMouseLeftButtonDown和Drop事件的行。隨着拖動&拖放工作正常。但是我無法再使用組合框中的鼠標進行選擇,該框打開,我可以看到內容,但是如果我想用鼠標選擇一個項目,它將選擇下拉列表的selectedItem下面的datagridrow。使用鍵盤上的上/下鍵我可以選擇。

private void ConfigurationFileView_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     DependencyObject source = e.OriginalSource as DependencyObject; 
     while (source != null && !(source is System.Windows.Controls.ComboBox)) 
      source = VisualTreeHelper.GetParent(source); 
     if (source != null) 
     { 
      // don't know what to do here.... 
     } 
     else 
     { 
      DataGrid dataGrid = (DataGrid)sender;     

      rowIndex = GetCurrentRowIndex(dataGrid, e.GetPosition); 
      if (rowIndex < 0) 
       return; 
      dataGrid.SelectedIndex = rowIndex; 
      ParameterVM selectedEmp = dataGrid.Items[rowIndex] as ParameterVM; 
      if (selectedEmp == null) 
       return; 
      DragDropEffects dragdropeffects = DragDropEffects.Move; 
      if (DragDrop.DoDragDrop(dataGrid, selectedEmp, dragdropeffects) != DragDropEffects.None) 
      { 
       dataGrid.SelectedItem = selectedEmp; 
      } 
     } 

    } 

private void ConfigurationFileView_Drop(object sender, DragEventArgs e) 
    { 
     DataGrid dataGrid = (DataGrid)sender; 

     int index = this.GetCurrentRowIndex(dataGrid, e.GetPosition); 
     if (index < 0) 
      return; 

     if (rowIndex < 0) 
     { 
      ParameterVM newParameter = e.Data.GetData(typeof(ParameterVM))as ParameterVM; 
      if (null == newParameter) 
       return; 

      ObservableCollection<ParameterVM> parameters = dataGrid.ItemsSource as ObservableCollection<ParameterVM>; 
      if (!parameters.Any(p => p.Name == newParameter.Name && p.Type == newParameter.Type)) 
      { 
       parameters.Insert(index, newParameter);  
      }     

     } 
     else 
     { 
      if (index == rowIndex) 
       return; 
      if (index == dataGrid.Items.Count - 1) 
      { 
       MessageBox.Show("This row-index cannot be drop"); 
       return; 
      } 

      ObservableCollection<ParameterVM> parameters = dataGrid.ItemsSource as ObservableCollection<ParameterVM>; 
      ParameterVM changedParameter = parameters[rowIndex]; 
      parameters.Move(rowIndex, index); 
     } 
    } 

我已經在這裏閱讀了一個答案來檢查dependencyobject是否是一個組合框。我試過了,但我不知道該怎麼做才能讓鼠標正確運行。

回答

0

最後我找到了一個適合我的解決方案。

我添加了兩個事件到DataGrid:

BeginningEdit="ConfigurationFileView_BeginningEdit" CellEditEnding="ConfigurationFileView_CellEditEnding" 

還增加了背後的一些代碼:

public bool IsEditing { get; set; } 

    private void ConfigurationFileView_BeginningEdit(object sender, DataGridBeginningEditEventArgs e) 
    { 
     IsEditing = true; 
    } 

    private void ConfigurationFileView_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e) 
    { 
     IsEditing = false; 
    } 

而在DropEvent我如果關於IsEditing增值的:

private void ConfigurationFileView_Drop(object sender, DragEventArgs e) 
     { 
      if (IsEditing) 
       return; 

      DataGrid dragSource = e.Data.GetData("DragSource") as DataGrid; 
      if (null == dragSource) 
       return; 

      DataGrid dropTarget = sender as DataGrid; 
      if (null == dropTarget) 
       return; 

      int index = this.GetCurrentRowIndex(dropTarget, e.GetPosition); 
      if (index < 0) 
       return;    

      ..... 
     }