我遇到了您的問題,並且遇到了同樣的問題。這是我的情況和解決方案,我認爲它也適用於你(和其他人)。我有一個允許輸入新項目的數據網格,所以可能的值從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數據網格會如此愚蠢。