2011-06-04 24 views
1

我使用類似於 http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/df77a277-91d4-41f1-a42a-0fa02a443ff4/ 的技術我有一個DaataGridTemplateColumn建,在代碼中,我試圖解決「選擇行,然後單擊」在WPF數據網格複選框問題。使用問題WPF

在一般意義上,這個工作,但是如果我想觸發一個事件時,該複選框被點擊(即CellEditEnding或RowEditEnding),好像我不能(根據http://social.msdn.microsoft.com/Forums/en/wpf/thread/bf080945-0092-43f5-b0eb-42b2edf53dc7

必須有一個解決這個問題的方法。我想過在我的模板列上使用某種路由事件來嘗試點擊複選框時觸發數據網格事件,但這可能會變得很難看。最終,我需要能夠有一個點擊複選框,並能夠觸發數據網格事件。

請幫忙!

編輯:如果我能只得到RowEditEnding火(不知何故:通過鼓泡或其他)那麼這將不會是一個問題......我根本無法得到它的火..

任何人? ?

謝謝

回答

0

答案在這裏是不處理任何複選框(或嘗試)在RowEditEnding。相反,使用PropertyChange事件監聽您綁定的複選框,並相應地採取行動(即在設置複選框的綁定時保存更改)

1

我遇到了您的問題,並且遇到了同樣的問題。這是我的情況和解決方案,我認爲它也適用於你(和其他人)。我有一個允許輸入新項目的數據網格,所以可能的值從0到無窮大。用戶應該能夠點擊複選框,並通過單擊一次按鈕來檢查或取消選中。另外,還有其他可以更新的字段。我不得不創建一個自定義的DataGrid控件自動對焦,並開始複選框編輯:

public class CheckboxDataGrid : DataGrid { 
     public CheckboxDataGrid() { 
      EventManager.RegisterClassHandler(typeof(DataGridCell), 
       DataGridCell.PreviewMouseLeftButtonDownEvent, 
       new RoutedEventHandler(this.OnPreviewMouseLeftButtonDown)); 
     } 


     private void OnPreviewMouseLeftButtonDown(object sender, RoutedEventArgs e) { 
      DataGridCell cell = sender as DataGridCell; 
      if (cell != null && !cell.IsEditing && !cell.IsReadOnly) { 

       var parentRow = cell.Parent as DataGridRow; 
       if (parentRow != null) { 
        SelectedIndex = parentRow.GetIndex(); 
       } 
       CurrentCell = new DataGridCellInfo(cell); 

       DependencyObject obj = FindVisualChild<CheckBox>(cell); 
       if (obj != null) { 
        BeginEdit(e); 
        System.Windows.Controls.CheckBox cb = (System.Windows.Controls.CheckBox)obj; 
        cb.Focus(); 
       } 
      } 
     } 
     public static TChild FindVisualChild<TChild>(DependencyObject obj) where TChild : DependencyObject { 
      for (int i = 0; i < VisualTreeHelper.GetChildrenCount(obj); i++) { 
       DependencyObject child = VisualTreeHelper.GetChild(obj, i); 
       if (child != null && child is TChild) { 
        return (TChild)child; 
       } else { 
        TChild childOfChild = FindVisualChild<TChild>(child); 
        if (childOfChild != null) 
         return childOfChild; 
       } 
      } 
      return null; 
     } 
    } 

我還需要一個轉換器忽略新項目,因爲WPF處理在DataGrid新項目的方式綁定消息:

public class IgnoreNewItemPlaceHolderConverter : IValueConverter { 
     private const string NewItemPlaceholderName = "{NewItemPlaceholder}"; 

     public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 
      return value; 
     } 

     public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { 
      if (value != null && value.ToString() == NewItemPlaceholderName) 
       return DependencyProperty.UnsetValue; 
      return value; 
     } 

    } 

這裏是DataGrid的relavent XAML:

<chkDatagrid:CheckboxDataGrid AutoGenerateColumns="False" 
         ItemsSource="{Binding ElementName=dgPurchaseOrders, Path=SelectedItem.Releases, NotifyOnSourceUpdated=True}" AlternatingRowBackground="#1E000000" 
         DockPanel.Dock="Bottom" HorizontalAlignment="Left" SelectedItem="{Binding SelectedRelease, Mode=TwoWay, Converter={StaticResource ignoreNewItemPlaceHolderConverter}}" 
         MinHeight="100"> 
<b:Interaction.Triggers> 
          <b:EventTrigger EventName="RowEditEnding"> 
           <b:InvokeCommandAction Command="{Binding ReleaseRowEditEndingCommand}" CommandParameter="{Binding SelectedRelease}"/> 
          </b:EventTrigger> 
         </b:Interaction.Triggers> 
         <DataGrid.Columns> 
          <DataGridCheckBoxColumn Header="Is Paid" Binding="{Binding IsPaid, UpdateSourceTrigger=PropertyChanged}" /> 

          <DataGridTextColumn Header="Amount" Binding="{Binding Amount, UpdateSourceTrigger=PropertyChanged}" /> 
          <DataGridTextColumn Header="Description" Binding="{Binding Description, UpdateSourceTrigger=PropertyChanged}" /> 
          <DataGridTextColumn Header="Invoice Number" Binding="{Binding InvoiceNumber, UpdateSourceTrigger=PropertyChanged}" /> 
          <DataGridTextColumn Header="Invoice Receive Date" Binding="{Binding InvoiceRecvDate, UpdateSourceTrigger=PropertyChanged}" /> 
         </DataGrid.Columns> 
        </chkDatagrid:CheckboxDataGrid> 

您會在這裏注意的幾件事情。我正在訂閱RowEditEnding事件來編輯和提交轉換器的列和應用程序到新行。

最後,這裏有一個更新的附加實體代碼:

private void OnReleaseRowEditEnding(object arg) { 
      if (arg != null) { 
       EMService.EMEntities etx = GetEMEntities(); 
       EMService.Release release = (EMService.Release)arg; 
       if (release.ReleaseID == 0) { 
        release.EncumbranceID = SelectedPurchaseOrder.EncumbranceID; 
        release.CreatedOn = DateTime.Now; 
        release.CreatedBy = CurrentUser.Username; 
        release.ModifiedOn = DateTime.Now; 
        release.ModifiedBy = CurrentUser.Username; 
        etx.AddObject("Releases", release); 
       } else { 
        EMService.Release existingRelease = etx.Releases.Where(e => e.ReleaseID == release.ReleaseID).First(); 
        existingRelease.Amount = release.Amount; 
        existingRelease.Description = release.Description; 
        existingRelease.InvoiceNumber = release.InvoiceNumber; 
        existingRelease.InvoiceRecvDate = release.InvoiceRecvDate; 
        existingRelease.IsPaid = release.IsPaid; 
        release.ModifiedOn = DateTime.Now; 
        release.ModifiedBy = CurrentUser.Username; 
        etx.UpdateObject(existingRelease); 
       } 
       etx.SaveChanges(); 
      } 
     } 

這是一個很大消化,但它結束了在長期運行工作。誰知道WPF數據網格會如此愚蠢。