Я сузил проблему до следующего примера с DataGrid с тремя столбцами.
XAML:
<Window x:Class="DataGridColumnTemplate_NotFiringAddingNewItem.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525">
<Grid>
<DataGrid x:Name="dg" HorizontalAlignment="Left" Margin="10,10,0,0" VerticalAlignment="Top" Height="299" AutoGenerateColumns="False" Width="497" AddingNewItem="dg_AddingNewItem" CanUserAddRows="True">
<DataGrid.Columns>
<DataGridTemplateColumn Header="DateWorks">
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding InvoiceDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="DateDoesn'tWork">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding InvoiceDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker SelectedDate="{Binding InvoiceDate}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
<DataGridTextColumn Header="Text" Binding="{Binding Description}"/>
</DataGrid.Columns>
</DataGrid>
</Grid>
</Window>
С#:
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
List<JobCostEntity> l = new List<JobCostEntity>()
{
new JobCostEntity() { Id = 0, InvoiceDate = DateTime.Now, Description = "A"},
new JobCostEntity() { Id = 0, InvoiceDate = DateTime.Now, Description = "B"}
};
dg.ItemsSource = l;
}
private void dg_AddingNewItem(object sender, AddingNewItemEventArgs e)
{
MessageBox.Show("AddingNewItem");
}
}
public partial class JobCostEntity
{
public int Id { get; set; }
public int JobId { get; set; }
public Nullable<int> JobItemId { get; set; }
public Nullable<System.DateTime> InvoiceDate { get; set; }
public Nullable<System.DateTime> ProcessedDate { get; set; }
public int PackageId { get; set; }
public int DelegateId { get; set; }
public string Description { get; set; }
public Nullable<decimal> LabourCost { get; set; }
public Nullable<decimal> PlantOrMaterialCost { get; set; }
public Nullable<decimal> SubcontractorCost { get; set; }
public Nullable<decimal> TotalCost { get; set; }
public bool Paid { get; set; }
}
Если первый столбец, который вы нажимаете в строке нового элемента, - "DateWorks" или "Текст", вы поднимете событие AddingNewItem.
Если вместо этого вы сначала нажмете столбец "DateDoesntWork", вы можете выбрать дату, но новый элемент не будет добавлен до тех пор, пока вы не перейдете к одному из других столбцов, после чего значение в "DateDoesntWork" DatePicker будет очищено.
Что происходит?
Возможно, (!) желательно, чтобы DatePicker уже был видимым пользователю (следовательно, и CellTemplate и CellEditingTemplate), а не им нужно щелкнуть ячейку, чтобы "открыть" элемент управления.
Есть ли способ сообщить DataGrid, что мой DataGridTemplateColumn Control только что установил значение в новой строке? Если да, то как??
EDIT:
Вдохновленный этой записью: https://social.msdn.microsoft.com/Forums/vstudio/en-US/93d66047-1469-4bed-8fc8-fa5f9bdd2166/programmatically-beginning-edit-in-datagrid-cell?forum=wpf
Я попытался взломать проблему, добавив следующее в столбец DateDoesntWork DatePicker, который вызывает событие AddingNewItem, но выбранная дата до сих пор не добавляется в базовый объект.
private void DatePicker_GotFocus(object sender, RoutedEventArgs e)
{
if (dg.SelectedIndex == dg.Items.Count - 1)
{
DataGridCellInfo dgci = dg.SelectedCells[0];
DataGridCell dgc = DataGridHelper.GetCell(dg, GetRowIndex(dg, dgci), GetColIndex(dg, dgci));
dgc.Focus();
dg.BeginEdit();
}
}
Кажется, что DatePicker все еще пытается настроить таргетинг на NewItemPlaceholder, если это имеет смысл?!
Незнакомец, если вы выберете дату в столбце DateDoesntWork в новой строке, затем начните редактирование столбца "Текст" в новой строке, затем без ввода какого-либо текста выберите строку выше... теперь добавляется еще одна новая строка и что новая добавленная строка показывает дату, выбранную для строки до этого.
Total. Безумие.
Как отметил Максим Тремблей-Савард, похоже, что CellTemplate
блокирует "уровень" ниже и останавливает запуск события AddingNewItem
, хотя встроенные типы DataGridColumn
не страдают от этой проблемы.