2011-11-07 34 views
7

Tôi có một DataGridComboBoxColum trong một DataGrid. Tôi muốn có thể nhấp vào ô một lần và thả xuống hộp tổ hợp. Hiện tại tôi phải bấm nhiều lần.DataGridComboBoxColumn - Tự động thả xuống trên một cú nhấp chuột

<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

Bạn có cần 'cái DataGrid' để đi vào chế độ chỉnh sửa, ví dụ nâng cao BeginningEditEvent? – XAMeLi

+0

Tôi chưa bao giờ nâng cao sự bắt đầu. Tôi có cần phải? –

+1

Nhấp chuột đầu tiên trên một ô là thiết lập tiêu điểm trên ô và (có thể) chọn nó (phụ thuộc vào SelectionMode của 'DataGrid'), nhấp chuột thứ hai hiển thị EditingElement và đó là khi BeginningEditEvent được nâng lên (bởi' DataGrid '). Vì vậy, tôi hiểu rằng bạn không xử lý sự kiện này, cũng như logic của bạn không phụ thuộc vào việc 'DataGrid' đang ở chế độ chỉnh sửa (tức là IsEditingCurrentCell == true hay IsEditingRowItem == true), phải không? – XAMeLi

Trả lời

6

One-click DataGridComboBoxColumn chỉnh sửa + một cú nhấp chuột chỉnh sửa CheckboxColumn
Xem thêm: 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> 

Mã-đằng sau:

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

"Xem thêm" là cách thực hiện. Sử dụng một DataGridTemplateColumn và thiết lập CellTemplate của nó vào một ComboBox. – user1454265

2

tôi đã vấn đề với @su Câu trả lời của rfen, có lẽ vì nhiều năm sau đó và WPF có lẽ đã thay đổi khá nhiều. Có vẻ như DataGrid hiện đang xử lý một số việc cho bạn, như chỉnh sửa trường văn bản tự động khi bạn bắt đầu nhập.

Tôi sử dụng DataGridTemplateColumn cho cột hộp kết hợp của mình. Mẫu có một số TextBlock cho số CellTemplate của nó. Cuộc gọi đến BeginEdit theo sau là cuộc gọi điều phối khiến hộp kết hợp xuất hiện trong cây thị giác. Sau đó nó xuất hiện rằng nhấp chuột được gửi đến hộp combo và nó sẽ tự mở.

Dưới đây là phiên bản sửa đổi của tôi mã @ surfen của:

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; 
    } 
} 
Các vấn đề liên quan