2011-11-07 8 views
7

DataGrid에 DataGridComboBoxColum이 있습니다. 셀을 한 번 클릭하고 콤보 상자를 드롭 다운 할 수 있기를 원합니다. 현재 나는 여러 번 클릭해야합니다.DataGridComboBoxColumn - 한 번의 클릭으로 자동 드롭

<DataGrid AutoGenerateColumns="False" Height="148" HorizontalAlignment="Left" Margin="48,85,0,0" Name ="dg_display" VerticalAlignment="Top" Width="645" CanUserAddRows="False" CanUserDeleteRows="False" ItemsSource="{Binding}" SelectionChanged="DgDisplaySelectionChanged"> 
     <DataGrid.Columns> 
      <DataGridTextColumn IsReadOnly="True" Header="Symbol" Binding="{Binding Symbol}" /> 
      <DataGridTextColumn IsReadOnly="True" Header="Company ID" Binding="{Binding CompanyID}" /> 
      <DataGridComboBoxColumn IsReadOnly="False" Header="Sector" SelectedValueBinding="{Binding Sector}" DisplayMemberPath="{Binding [0]}" Visibility="Visible" > 
       <DataGridComboBoxColumn.EditingElementStyle> 
        <Style TargetType="ComboBox"> 
         <Setter Property="ItemsSource" Value="{Binding SectorList}" /> 
        </Style> 
       </DataGridComboBoxColumn.EditingElementStyle> 
       <DataGridComboBoxColumn.ElementStyle> 
        <Style TargetType="ComboBox"> 
         <Setter Property="ItemsSource" Value="{Binding SectorList}" /> 
        </Style> 
       </DataGridComboBoxColumn.ElementStyle> 
      </DataGridComboBoxColumn> 
     </DataGrid.Columns> 
    </DataGrid> 
+0

, 당신은'DataGrid'가 편집 모드로 전환해야합니까 즉이 BeginningEditEvent을 제기은? – XAMeLi

+0

나는 시작된 사건을 결코 제기하지 않는다. 내가 할 필요가 있니? –

+1

셀의 첫 번째 클릭은 셀에 포커스를 설정하고 (아마) (DataGrid의 SelectionMode에 따라) 선택합니다. 두 번째 클릭에는 EditingElement가 표시되고 BeginningEditEvent가 발생합니다 (DataGrid '). 그래서 당신이이 사건을 다루지 않는다는 것과 논리가'DataGrid'가 편집 모드 (IsEditingCurrentCell == true 또는 IsEditingRowItem == true)인지 여부에 의존하지 않는다는 것을 이해합니다. 맞습니까? – XAMeLi

답변

6

한 번의 클릭으로도 DataGridComboBoxColumn 편집 + 한 번의 클릭으로 CheckboxColumn 편집
참조 : https://stackoverflow.com/a/8333704/724944

XAML :

 <Style TargetType="{x:Type DataGridCell}"> 
      <EventSetter Event="PreviewMouseLeftButtonDown" Handler="DataGridCell_PreviewMouseLeftButtonDown" /> 
      <EventSetter Event="PreviewTextInput" Handler="DataGridCell_PreviewTextInput" /> 
     </Style> 

코드 숨김 내가 가진

private void DataGridCell_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     DataGridCell cell = sender as DataGridCell; 
     GridColumnFastEdit(cell, e); 
    } 

    private void DataGridCell_PreviewTextInput(object sender, TextCompositionEventArgs e) 
    { 
     DataGridCell cell = sender as DataGridCell; 
     GridColumnFastEdit(cell, e); 
    } 

    private static void GridColumnFastEdit(DataGridCell cell, RoutedEventArgs e) 
    { 
     if (cell == null || cell.IsEditing || cell.IsReadOnly) 
      return; 

     DataGrid dataGrid = FindVisualParent<DataGrid>(cell); 
     if (dataGrid == null) 
      return; 

     if (!cell.IsFocused) 
     { 
      cell.Focus(); 
     } 

     if (cell.Content is CheckBox) 
     { 
      if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow) 
      { 
       if (!cell.IsSelected) 
        cell.IsSelected = true; 
      } 
      else 
      { 
       DataGridRow row = FindVisualParent<DataGridRow>(cell); 
       if (row != null && !row.IsSelected) 
       { 
        row.IsSelected = true; 
       } 
      } 
     } 
     else 
     { 
      ComboBox cb = cell.Content as ComboBox; 
      if (cb != null) 
      { 
       //DataGrid dataGrid = FindVisualParent<DataGrid>(cell); 
       dataGrid.BeginEdit(e); 
       cell.Dispatcher.Invoke(
       DispatcherPriority.Background, 
       new Action(delegate { })); 
       cb.IsDropDownOpen = true; 
      } 
     } 
    } 


    private static T FindVisualParent<T>(UIElement element) where T : UIElement 
    { 
     UIElement parent = element; 
     while (parent != null) 
     { 
      T correctlyTyped = parent as T; 
      if (correctlyTyped != null) 
      { 
       return correctlyTyped; 
      } 

      parent = VisualTreeHelper.GetParent(parent) as UIElement; 
     } 
     return null; 
    } 
+0

"보기"는이를 수행하는 방법입니다. DataGridTemplateColumn을 사용하고 해당 CellTemplate을 ComboBox로 설정합니다. – user1454265

2

을 @su 문제 아마도 몇 년 후에 WPF가 아마도 꽤 많이 바뀌었기 때문일 것입니다. 입력을 시작하면 DataGrid이 자동으로 텍스트 필드를 수정하는 것처럼 몇 가지 사항을 처리합니다.

내 콤보 상자 열에 DataGridTemplateColumn을 사용합니다. 템플릿의 CellTemplateTextBlock입니다. BeginEdit 다음에 dispatcher 호출을 호출하면 콤보 상자가 시각적 트리에 나타납니다. 그런 다음 마우스 클릭이 콤보 상자로 보내지고 자체적으로 열리는 것으로 나타납니다.

여기 @ surfen의 코드 내 수정 된 버전입니다 :

public static class DataGridExtensions 
{ 
    public static void FastEdit(this DataGrid dataGrid) 
    { 
     dataGrid.ThrowIfNull(nameof(dataGrid)); 

     dataGrid.PreviewMouseLeftButtonDown += (sender, args) => { FastEdit(args.OriginalSource, args); }; 
    } 

    private static void FastEdit(object source, RoutedEventArgs args) 
    { 
     var dataGridCell = (source as UIElement)?.FindVisualParent<DataGridCell>(); 

     if (dataGridCell == null || dataGridCell.IsEditing || dataGridCell.IsReadOnly) 
     { 
      return; 
     } 

     var dataGrid = dataGridCell.FindVisualParent<DataGrid>(); 

     if (dataGrid == null) 
     { 
      return; 
     } 

     if (!dataGridCell.IsFocused) 
     { 
      dataGridCell.Focus(); 
     } 

     if (dataGridCell.Content is CheckBox) 
     { 
      if (dataGrid.SelectionUnit != DataGridSelectionUnit.FullRow) 
      { 
       if (!dataGridCell.IsSelected) 
       { 
        dataGridCell.IsSelected = true; 
       } 
      } 
      else 
      { 
       var dataGridRow = dataGridCell.FindVisualParent<DataGridRow>(); 

       if (dataGridRow != null && !dataGridRow.IsSelected) 
       { 
        dataGridRow.IsSelected = true; 
       } 
      } 
     } 
     else 
     { 
      dataGrid.BeginEdit(args); 

      dataGridCell.Dispatcher.Invoke(DispatcherPriority.Background, new Action(() => { })); 
     } 
    } 
} 

public static class UIElementExtensions 
{ 
    public static T FindVisualParent<T>(this UIElement element) 
     where T : UIElement 
    { 
     UIElement currentElement = element; 

     while (currentElement != null) 
     { 
      var correctlyTyped = currentElement as T; 

      if (correctlyTyped != null) 
      { 
       return correctlyTyped; 
      } 

      currentElement = VisualTreeHelper.GetParent(currentElement) as UIElement; 
     } 

     return null; 
    } 
} 
관련 문제