c# - 日期选择器问题需要在开始编辑时使用两次,在单元格更改时使用 WPF 数据网格

c# - Issue with Date Picker needed to be used twice with Begin Edit and a Data Grid with WPF on cell change

这是一个 C# 中的 WPF 应用程序,使用带有日期选择器的数据网格作为单元格。

目标是单击日历,select 日期,然后数据网格进入编辑模式,因此只要单击另一个单元格,就会对数据库和行进行更新已添加到网格上,该部分正在运行。

但是,当我最初单击日期选择器时,select 日期,因为我执行数据网格开始编辑,日期 selected 从未显示在控件中,它会在编辑模式下,此时我仍然可以单击另一个单元格以在数据库中插入并将行添加到数据网格,但日期插入为空(我也可以再次 select 日期在日期选择器上单击另一个单元格以将日期添加到数据库并在数据网格中添加行)。

有没有办法改变这种行为,以便保留所选日期并且它仍然进入编辑模式,而无需再次单击日期选择器,select 再次选择日期,然后单击另一个用于插入的单元格?

你能帮我解决这个问题吗?

这是创建列的代码(使用模板):

            templateColumn = new DataGridTemplateColumn();
            templateColumn.Header = "Date time";
            FrameworkElementFactory datePickerFactoryElem = new FrameworkElementFactory(typeof(DatePicker));
            templateColumnBinding = new Binding("date_time");
            templateColumnBinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
            templateColumnBinding.Mode = BindingMode.TwoWay;
            datePickerFactoryElem.AddHandler(DatePicker.SelectedDateChangedEvent, new EventHandler<SelectionChangedEventArgs>(RowEditEnding));
            datePickerFactoryElem.SetValue(DatePicker.SelectedDateProperty, templateColumnBinding);
            datePickerFactoryElem.SetValue(DatePicker.DisplayDateProperty, templateColumnBinding);
            cellTemplate.VisualTree = datePickerFactoryElem;
            templateColumn.CellTemplate = cellTemplate;

            dataGrid.Columns.Add(templateColumn);

这是我使用日期选择器 select 一个日期时开始编辑的代码:

        private void RowEditEnding(object sender, SelectionChangedEventArgs e)
        {
            dataGrid.BeginEdit();
        }

这是我单击另一个单元格时触发的代码:


        private void dataGrid_CellEditEnding(object sender, DataGridCellEditEndingEventArgs e)
        {
            if (!isManualEditCommit)
            {
                isManualEditCommit = true;
                DataGrid grid = (DataGrid)sender;
                grid.CommitEdit(DataGridEditingUnit.Row, true);
                isManualEditCommit = false;
            }
        }

        private void dataGrid_RowEditEnding(object sender, DataGridRowEditEndingEventArgs e)
        {
            DataRowView rowView = e.Row.Item as DataRowView;
            rowBeingEdited_dataGrid = rowView;
        }

        private void dataGrid_CurrentCellChanged(object sender, EventArgs e)
        {
            if (rowBeingEdited_dataGrid != null)
            {
                dataGrid.CommitEdit();

                conn = new MySqlConnection(connStr);

                MySqlCommand cmdInsert;
                MySqlCommand cmdUpdate;
                cmdUpdate = new MySqlCommand(@"UPDATE…
                                SET…
                                WHERE…;", conn);
                cmdUpdate.Parameters.Add("…");
                cmdUpdate.Parameters.Add("…");
                cmdInsert = new MySqlCommand(@"INSERT INTO…
                            (…,
                            …,)
                            VALUES
                            …,
                            …);", conn);
                cmdInsert.Parameters.Add("…");
                cmdInsert.Parameters.Add("…");

                mySqlDataAdapter.InsertCommand = cmdInsert;
                mySqlDataAdapter.UpdateCommand = cmdUpdate;

                mySqlDataAdapter.Update(dataSet);
                conn.Close();
                conn.Dispose();

                dataGrid.ItemsSource = null;
                dataSet.Reset();

                rowBeingEdited_DataGrid.EndEdit();
                rowBeingEdited_DataGrid = null;

                conn = new MySqlConnection(connStr);
                mySqlDataAdapter = new MySqlDataAdapter(@"select * from …", conn);
                command = conn.CreateCommand();
                conn.Open();

                mySqlDataAdapter.Fill(dataSet);
                dataGrid.ItemsSource = dataSet.Tables[0].DefaultView;
                conn.Close();
                conn.Dispose();
            }
        }

感谢您的宝贵时间和帮助,非常感谢。

注意:变量名和控件在原代码中的命名更好,我尽量删除了不相关的信息,这样代码更容易阅读。

以下是我解决问题的方法:

        templateColumn = new DataGridTemplateColumn();
        templateColumn.Header = "Date time";
        FrameworkElementFactory datePickerFactoryElem = new FrameworkElementFactory(typeof(DatePicker));
        FrameworkElementFactory datePickerFactoryElem_01 = new FrameworkElementFactory(typeof(TextBlock));
        templateColumnBinding = new Binding("date_time");
        templateColumnBinding.UpdateSourceTrigger = UpdateSourceTrigger.Default;
        templateColumnBinding.Mode = BindingMode.TwoWay;
        datePickerFactoryElem.SetValue(DatePicker.SelectedDateProperty, templateColumnBinding);
        datePickerFactoryElem.SetValue(DatePicker.DisplayDateProperty, templateColumnBinding);
        cellTemplate.VisualTree = datePickerFactoryElem;
        cellTemplate_01.VisualTree = datePickerFactoryElem_01;
        templateColumn.CellEditTemplate = cellTemplate;
        templateColumn.CellTemplate = cellTemplate_01;

        dataGrid.Columns.Add(templateColumn);

基本上,我使用 TextBlock 来显示数据,每当该文本框被单击两次时,DataGrid 进入编辑模式并且 DatePicker 出现,所以我可以用它来 select 日期。之后,每当我点击另一个单元格时,数据库就会正确更新。阅读以下内容后,我改变了处理编辑的方式:

DataGridTemplateColumn (ComboBox, DatePicker) Resets/Clears and doesn't fire AddingNewItem