我正在使用类似的技术 http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/df77a277-91d4-41f1-a42a-0fa02a443ff4/ 我在代码中构建了DaataGridTemplateColumn,我正在尝试解决WPF中数据网格的“选择行,然后单击”复选框问题。
在一般意义上,这是有效的,但是如果我想在单击复选框时触发事件(即CellEditEnding或RowEditEnding),似乎我不能(根据http://social.msdn.microsoft.com/Forums/en/wpf/thread/bf080945-0092-43f5-b0eb-42b2edf53dc7)
必须有办法解决这个问题。我想在我的模板列上使用某种路由事件,试图在单击复选框时触发数据网格事件,但这可能会变得很难看。最终,我需要能够有一个单击复选框,并能够触发数据网格事件。
请帮忙!
编辑:如果我可以让RowEditEnding开火(不知何故:通过。冒泡或其他什么)那么这不会是一个问题......我根本无法解决它......
有人???
谢谢
答案 0 :(得分:1)
我遇到了你的问题并遇到了同样的问题。这是我的情况和解决方案,我认为它应该适用于你(和其他人)。我有一个允许输入新项目的数据网格,因此可能的值从0到无穷大。用户应该能够单击该复选框,只需单击一下按钮即可选中或取消选中。此外,还有其他字段也可以更新。我必须创建一个自定义数据网格控件来自动聚焦并开始编辑复选框:
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处理数据网格中新项目的方式,我还需要一个转换器来忽略新的项目绑定消息:
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的相关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数据网格会如此懒散。
答案 1 :(得分:0)
这里的答案是不处理RowEditEnding中的任何复选框(或尝试)。相反,使用PropertyChange事件侦听您绑定的复选框,并相应地执行操作(即在设置复选框的绑定时保存更改)