C# 输入下一个字段时,输入的日期消失
我将DatePicker嵌入到绑定到MySQL数据库的DataGrid中。问题是,当用户输入日期,然后开始在DataGrid的下一个字段中输入数据时,日期就会消失 如果这是一个bug,那么可能有一个解决方法。如果我的代码中有遗漏或不正确的地方,那么我希望得到启发 我将在解决问题的步骤之后粘贴代码的概要。Microsoft Visual Studio Community 2019项目的所有文件将暂时可在以下位置下载: 设置: 将iacc_core.zip解压到您选择的目录中 子目录acc_db包含MySQL模式和数据。希望您可以在MySQL Workbench中进行数据导入,用测试数据加载测试方案。这个问题可能与MySQL无关,因此绑定到MySQL数据库以外的其他数据库也可能引发问题 您需要调整目录路径并设置数据库连接(如果使用示例数据数据库) 步骤:C# 输入下一个字段时,输入的日期消失,c#,mysql,wpf,datepicker,datagrid,C#,Mysql,Wpf,Datepicker,Datagrid,我将DatePicker嵌入到绑定到MySQL数据库的DataGrid中。问题是,当用户输入日期,然后开始在DataGrid的下一个字段中输入数据时,日期就会消失 如果这是一个bug,那么可能有一个解决方法。如果我的代码中有遗漏或不正确的地方,那么我希望得到启发 我将在解决问题的步骤之后粘贴代码的概要。Microsoft Visual Studio Community 2019项目的所有文件将暂时可在以下位置下载: 设置: 将iacc_core.zip解压到您选择的目录中 子目录acc_db包含
代码隐藏:
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Data;
using System.Linq;
using System.Windows;
using System.Windows.Automation.Peers;
using System.Windows.Automation.Provider;
using System.Windows.Controls;
using System.Windows.Input;
using System.Windows.Media;
using MySql.Data.MySqlClient;
using MySqlX.XDevAPI.Relational;
using iacc_core;
namespace iacc
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private readonly string conn_str = "server=chevron;user id=admin;password=admin;database=indinfer_accounting;allowuservariables=True;persistsecurityinfo=True";
private MySql_F data_transactions = null;
private bool FirstKeyOrClick = false;
private MySql_F data_lines = null;
public MainWindow()
{
InitializeComponent();
string sel_str = "SELECT uid, date_trans, reference, contact, description FROM transactions ORDER BY uid";
data_transactions = MySql_F.DataGrid_CRUD_DataSource(DataGrid_Transactions, conn_str, sel_str);
DataGrid_Transactions.Focus();
DataGrid_Transactions.ScrollIntoView(DataGrid_Transactions.Items[Last_Index(DataGrid_Transactions.Items.Count)]);
DataGrid_Transactions.SelectedIndex = Last_Index(DataGrid_Transactions.Items.Count);
// Now get the detail grid working. Get the id from the *** DataTable *** that is the source for DataGrid_Transactions
}
private int Last_Index(int count)
{
return ((count <= 1) ? 0 : count - 1);
}
private void Window_Closing(object sender, System.ComponentModel.CancelEventArgs e)
{
data_transactions.Update_Database();
}
private bool init_datagrid_transactions()
{
if (FirstKeyOrClick)
{
return false;
}
FirstKeyOrClick = true;
// Give DataGrid_Transactions keyboard focus on the last row
DataGrid_Transactions.MoveFocus(new TraversalRequest(FocusNavigationDirection.Last));
// Cause DataGrid_Transactions to accept input on key press instead of transferring focus to next control
Keyboard_F.SendKey(Key.Home);
Keyboard_F.SendKey(Key.Home);
return true;
}
private void DataGrid_Transactions_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
{
if (init_datagrid_transactions())
{
e.Handled = true;
}
}
private void DataGrid_Transactions_KeyDown(object sender, KeyEventArgs e)
{
if (init_datagrid_transactions())
{
e.Handled = true;
}
}
private void Button_update_transaction_lines_Click(object sender, RoutedEventArgs e)
{
/*
* Get item index from DataGrid_Transactions. Use index to get ID from the bound DataTable.
* Use function from Adapter to update DataGrid_Lines. The ID is a parameter for this.
*/
int idx = DataGrid_Transactions.SelectedIndex;
TextBox_trans_row.Text = idx.ToString();
if (idx <= DataGrid_Transactions.Items.Count)
{
DataRow dr = data_transactions.data_table.Rows[idx];
TextBox_trans_id.Text = dr.Field<int>("uid").ToString();
string select_sql =
"SELECT uid, uid_transaction, line_num, entity, financial_stmt, " +
"acct_group, acct_path, line_description, quantity, multiplier, amount " +
"FROM transaction_lines " +
"WHERE(uid_transaction = " + idx.ToString() + ") " +
"ORDER BY line_num";
string insert_sql =
"INSERT INTO transaction_lines " +
"(uid_transaction, line_num, entity, financial_stmt, acct_group, " +
"acct_path, line_description, quantity, multiplier, amount) " +
"VALUES(@uid_transaction, @line_num, @entity, @financial_stmt, @acct_group, " +
"@acct_path, @line_description, @quantity, @multiplier, @amount)";
string update_sql = "UPDATE transaction_lines " +
"SET uid_transaction = @uid_transaction, " +
"line_num = @line_num, " +
"entity = @entity, " +
"financial_stmt = @financial_stmt, " +
"acct_group = @acct_group, " +
"acct_path = @acct_path, " +
"line_description = @line_description, " +
"quantity = @quantity, " +
"multiplier = @multiplier, " +
"amount = @amount " +
"WHERE(transaction_lines.uid = @uid)";
string delete_sql =
"DELETE FROM transaction_lines " +
"WHERE(transaction_lines.uid = @uid)";
data_lines = MySql_F.DataGrid_CRUD_DataSource(DataGrid_Lines, conn_str,
select_sql, insert_sql, update_sql, delete_sql);
}
}
private void DataGrid_Transactions_InitializingNewItem(object sender, InitializingNewItemEventArgs e)
{
}
private void dg_tr_cell_date_picker_GotFocus(object sender, RoutedEventArgs e)
{
}
}
}
使用系统;
使用系统集合;
使用System.Collections.Generic;
使用System.Collections.ObjectModel;
使用系统数据;
使用System.Linq;
使用System.Windows;
使用System.Windows.Automation.Peers;
使用System.Windows.Automation.Provider;
使用System.Windows.Controls;
使用System.Windows.Input;
使用System.Windows.Media;
使用MySql.Data.MySqlClient;
使用MySqlX.XDevAPI.Relational;
使用iacc_内核;
名称空间iacc
{
///
///MainWindow.xaml的交互逻辑
///
公共部分类主窗口:窗口
{
私有只读字符串conn_str=“server=chevron;user id=admin;password=admin;database=indinfer\u accounting;allowuservariables=True;persistsecurityinfo=True”;
私有MySql\u F data\u transactions=null;
private bool FirstKeyOrClick=false;
私有MySql\u F data\u line=null;
公共主窗口()
{
初始化组件();
string sel_str=“按uid从交易订单中选择uid、日期、交易、参考、联系人、描述”;
data_transactions=MySql_F.DataGrid_CRUD_数据源(DataGrid_transactions,conn_str,sel_str);
DataGrid_Transactions.Focus();
DataGrid_Transactions.ScrollIntoView(DataGrid_Transactions.Items[Last_Index(DataGrid_Transactions.Items.Count)];
DataGrid\u Transactions.SelectedIndex=上次索引(DataGrid\u Transactions.Items.Count);
//现在获取详细的网格工作。从***数据表***获取id,该表是DataGrid\u事务的源
}
私有整数最后索引(整数计数)
{
return((count将DatePicker
放在CellTemplate
中是错误的。输入字段应放在CellEditingTemplate
中,以便按预期保存编辑的值。CellTemplate
应仅显示当前值,例如使用TextBlock
:
<DataGridTemplateColumn x:Name="col_date" Header="Date" Width="100" >
<DataGridTemplateColumn.CellTemplate >
<DataTemplate >
<TextBlock Text="{Binding date_trans, StringFormat=MM/dd/yyyy}" TextAlignment="Right" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker Name="dg_tr_cell_date_picker"
SelectedDate="{Binding date_trans, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
TextBlock.TextAlignment="Right" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
其他类型的列就是这样工作的。将日期选择器
放在CellTemplate
中是错误的。输入字段应该放在CellEditingTemplate
中,以便按预期保存编辑后的值。CellTemplate
应该只显示当前值,例如使用>文本块
:
<DataGridTemplateColumn x:Name="col_date" Header="Date" Width="100" >
<DataGridTemplateColumn.CellTemplate >
<DataTemplate >
<TextBlock Text="{Binding date_trans, StringFormat=MM/dd/yyyy}" TextAlignment="Right" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker Name="dg_tr_cell_date_picker"
SelectedDate="{Binding date_trans, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
TextBlock.TextAlignment="Right" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
这就是其他类型的列的工作方式。我感谢@mm8给出了一个好的答案。这个答案帮助开发了一个替代方案。这个替代方案允许DatePicker按钮随时出现。这似乎是一个风格偏好的问题,因为您不使用这个替代方案保存单击或击键
从@mm8发布的代码的同一部分中,替换为:
<DataGridTemplateColumn x:Name="col_date" Header="Date" Width="100" >
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<DatePicker Name="dg_tr_cell_date_picker"
SelectedDate="{Binding date_trans, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
TextBlock.TextAlignment="Right"
IsHitTestVisible="False" Focusable="False" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<DatePicker Name="dg_tr_cell_date_picker"
SelectedDate="{Binding date_trans, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged,
ValidatesOnExceptions=True, NotifyOnValidationError=True}"
TextBlock.TextAlignment="Right"
Background="Green" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
我认为IshitteVisible和Focusable会阻止在正常模式下进行编辑。我会支持某人对原因的解释。这似乎是防止数据采集器丢失数据的原因,即使数据采集器在同一列中出现两次
我补充说
Background="Green"
切换到可编辑版本,使编辑模式和正常模式之间的转换变得明显。背景颜色并不是此解决方案工作的原因。我感谢@mm8提供的良好支持
Background="Green"