Сводка
В моем приложении у меня есть WPF DataGrid с несколькими DataGridTemplateColumns. По какой-то причине пользователь не может вручную добавить строки в DataGrid, нажав клавишу Enter. У меня есть другие DataGrids, где есть только DataGridTextcolumns. В этой DataGrid пользователь может добавлять новые строки, нажимая клавишу Enter.
Описание
Я могу воспроизвести проблему с небольшим приложением с тремя DataGrids.
ПервыйDataGrid содержит только DataGridTextColumn. Если я щелкну начальную строку в столбце, я могу напечатать что-нибудь в столбце и нажать клавишу ввода. Это автоматически создаст новую строку, и моя коллекция ObservableCollection будет автоматически обновлена, содержащая 1 элемент для строки, которую я только что создал. Так что, похоже, это работает как ожидалось.
Второй DataGrid содержит только DataGridTemplateColumn со Slider. Но с этой DataGrid я не могу добавить новую строку в качестве первой. Я просто хочу установить значение ползунка и нажать клавишу Enter. Затем я хочу новую строку с другим ползунком в DataGrid.
В моем третьем DataGrid я объединил две сетки с DataGridTextColumn и DataGridTemplateColumn с той же настройкой. В этой DataGrid я могу добавить новую строку только в том случае, если я нажму клавишу Enter в DataGridTextColumn.
Code
Ниже представлен воспроизводимый код. Просто создайте новое приложение WPF под названием WpfApp1 в VS и скопируйте вставку в MainWindow.xaml и MainWindow.xaml.cs.
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:WpfApp1"
mc:Ignorable="d"
Title="MainWindow" Height="600" Width="800">
<Window.DataContext>
<local:ViewModel />
</Window.DataContext>
<StackPanel Orientation="Vertical">
<Label Content="Can create a new row manually in the grid by hitting enter in the 'Text' column" Margin="0,20,0,0" />
<DataGrid ItemsSource="{Binding Models1}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Text" Width="300" />
</DataGrid.Columns>
</DataGrid>
<Button Content="Summary" Height="40" Click="Button_Click" Margin="0,20,0,20" />
<Label Content="Can't create a new row manually in the grid by hitting enter" />
<DataGrid ItemsSource="{Binding Models2}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn Header="Number" Width="300">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Slider Value="{Binding Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="1" Maximum="300" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
<Label Content="Can create a new row manually in the grid by hitting enter in the 'Text' column" Margin="0,80,0,0" />
<DataGrid ItemsSource="{Binding Models3}" CanUserAddRows="True" CanUserDeleteRows="True" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTextColumn Binding="{Binding Text, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Header="Text" Width="100" />
<DataGridTemplateColumn Header="Number" Width="300">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<Slider Value="{Binding Number, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Minimum="1" Maximum="300" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
</StackPanel>
</Window>
using System;
using System.ComponentModel;
using System.Collections.ObjectModel;
using System.Linq;
using System.Windows;
namespace WpfApp1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var vm = DataContext as ViewModel;
var t1 = $"All text: {string.Join(", ", vm.Models1.Select(r => r.Text))}";
var t2 = $"All numbers: {string.Join(", ", vm.Models2.Select(r => r.Number))}";
var t3 = $"All numbers: {string.Join(", ", vm.Models3.Select(r => r.Number))}";
MessageBox.Show($"Summary: {Environment.NewLine} {t1} {Environment.NewLine} {t2} {Environment.NewLine} {t3}");
}
}
class Model : INotifyPropertyChanged
{
string text;
double number;
public event PropertyChangedEventHandler PropertyChanged;
public Model()
{
Console.WriteLine("");
}
public string Text
{
get { return text; }
set
{
if (value != text)
{
text = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Text)));
}
}
}
public double Number
{
get { return number; }
set
{
if (value != number)
{
number = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Number)));
}
}
}
}
class ViewModel
{
public ObservableCollection<Model> Models1 { get; private set; }
public ObservableCollection<Model> Models2 { get; private set; }
public ObservableCollection<Model> Models3 { get; private set; }
public ViewModel()
{
Models1 = new ObservableCollection<Model>();
Models2 = new ObservableCollection<Model>();
Models3 = new ObservableCollection<Model>();
}
}
}
Другое
Я подозреваю, что DataGridTemploateColumn имеет другойповедение затем DataGridTextColumn. Это было бы полезно знать в будущем. Но проблема все еще существует.
Проблема проста: как вручную добавить новую строку в DataGrid, где есть один или несколько DataGridTemplateColumns?
Я нашел этот пост (Невозможно вставить строки в Datagrid с использованием DataGridTemplateColumn ) с более или менее такой же проблемой. Рекомендация состояла в том, чтобы изменить CellTemplate DataGridTemplateColumn на CellEditingTemplate. Но, похоже, это не решило мою проблему.