Я работаю над созданием DataGrid с той же функциональностью, что и Microsoft Dynamic Nav .
Это почти как электронная таблица Excel.
Идея состоит в том, что вы можете начать редактирование ячейки. После того, как вы закончите, есть несколько шагов:
Содержимое ячейки проверяется по списку.
1.1 Если список содержит заданную строку (без учета регистра), то содержимое в DataGrid заменяется строкой из списка (то есть, где регистр прав).
1.2 Если список не содержит строку, он покажет новую форму с возможностями, а затем использует ту, которую выберет пользователь, для замены уже введенной в DataGrid.
Если пользователь набрал что-то правильно или выбрал правильное значение из списка, DataGrid автоматически заполнит некоторые столбцы предварительно заданной строкой
Если мы посмотрим на пример: если пользователь вводит z в столбце 1, тогда я хочу, чтобы столбец 2 стал «x», а фокус переместился на colum3
DataGrid: (Before enter/Tab pressed)
[Column1] [Column2] [Column3] [Column4]
[ "a" ] [ "b" ] [ "c" ] [ "d" ]
[ "z" ] [ ] [ ] [ ]
(focused)
DataGrid: (Afture enter/tab pressed
[Column1] [Column2] [Column3] [Column4]
[ "a" ] [ "b" ] [ "c" ] [ "d" ]
[ "z" ] [ "x" ] [ ] [ ]
(focused)
Здесь я сталкиваюсь с некоторыми проблемами:
- Я использую событие
CellEditEnding
для проверки ввода текста. Если я найду правильный текст, тогда я отредактирую currentItem
в правильной переменной. Но теперь мне нужно позвонить dataGrid1.Items.Refresh();
, и это невозможно сделать в режиме редактирования.
MyCode:
FormTest.xaml
...
<DataGrid.Columns>
<DataGridTextColumn Header="C1"
Binding="{Binding c1,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C2"
Binding="{Binding c2,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C3"
Binding="{Binding c3,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C4"
Binding="{Binding c4,UpdateSourceTrigger=LostFocus}"/>
<DataGridTextColumn Header="C5"
Binding="{Binding c5,UpdateSourceTrigger=LostFocus}"/>
</DataGrid.Columns>
...
FormTest.xaml.cs
public FormTest()
{
InitializeComponent();
loadMockData();
}
private void loadMockData()
{
dataItems = new DataItems();
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataItems.Add(new DataItem() { c1 = "a", c2 = "b", c3 = "c", c4 = "d", c5 = "e" });
dataGrid1.ItemsSource = dataItems;
}
private void dataGrid1_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
{
TextBox editElement = e.EditingElement as TextBox;
DataItem di = dataGrid1.CurrentItem as DataItem;
DataGridCellInfo cell = dataGrid1.CurrentCell;
if (e.Column.DisplayIndex == 0)
{
if (editElement.Text == "z")
{
editElement.Text = "Z";
di.c1 = "Z";
di.c2 = "X";
}
}
}
private void dataGrid1_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (e.Key == Key.Enter || e.Key == Key.Tab)
{
dataGrid1.CommitEdit();
DataItem di = dataGrid1.CurrentItem as DataItem;
dataGrid1.CancelEdit();
dataGrid1.Items.Refresh();
}
}
private class DataItems : List<DataItem> { }
private class DataItem
{
public int recID { get; set; }
public String c1 { get; set; }
public String c2 { get; set; }
public String c3 { get; set; }
public String c4 { get; set; }
public String c5 { get; set; }
}
Проблемы, с которыми я сталкиваюсь в этом коде:
После вызова обновления выбранная ячейка отсутствует. Это означает, что невозможно продолжить ввод данных без использования мыши для выбора ячейки.
Когда я начинаю набирать новый элемент (он же пустая строка) и нажимаю клавишу ввода или табуляцию, dataGrid1.CancelEnding()
удалит новый элемент, и строка снова станет пустой.
Вопросы
- Можно ли редактировать содержимое таблицы данных (
ItemSoure
и что отображается) без вызова Items.Refresh()
?
- Если нет, можно установить фокус ячейки после выполнения
Items.Refresh()
.
- Или есть лучший способ сделать это?