简体   繁体   English

C# WPF 如何设置“更新”按钮来更改表格上一行的内容?

[英]C# WPF How do you set up an "Update" button to change the contents of a row on a table?

I am new to WPF and I am trying to figure out how to create an "Update" button that will show all the contents of a row on a table, allowing the user to change any category and save the new data.我是 WPF 的新手,我试图弄清楚如何创建一个“更新”按钮,该按钮将显示表格上一行的所有内容,允许用户更改任何类别并保存新数据。

What the main window would look like:主要的 window 会是什么样子:主窗口的外观

Then when the update button is clicked, a window looking like this would pop up.然后当点击更新按钮时,会弹出一个看起来像这样的 window。 : 一个看起来像这样的窗口会弹出。

How would you make the second window?你将如何制作第二个 window? Down below is what I have to show the main window without an "update" button.下面是我必须显示的主要 window 没有“更新”按钮。

**MainWindowxaml.cs**

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

using System.Collections;
using System.IO;

namespace Sort_a_list
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public class Student
        {
            public string name
            {
                get;
                set;
            }
            public int age
            {
                get;
                set;
            }
            public string gender
            {
                get;
                set;
            }
            public string major
            {
                get;
                set;
            }
            public string classification
            {
                get;
                set;
            }

        }
        public MainWindow()
        {
            InitializeComponent();
            List<Student> user = new List<Student>();
            try
            {
                using (StreamReader sr = new StreamReader(@"C:\Users\justi\Documents\2021 Self Study\WPF C#\Samples.txt"))
                {
                    string line;
                    char[] sep = { ',' };
                    int length;
                    ArrayList rows = new ArrayList();

                    while ((line = sr.ReadLine()) != null)
                    {
                        string[] words = line.Split(sep);
                        length = words.Length;
                        rows.Add(words);

                    }
                    string[] columns;
                    for(int i = 1; i < rows.Count; i++)
                    {
                        columns = (string[])rows[i];
                        user.Add(new Student() { name = columns[0], age = Int16.Parse(columns[1]), gender = columns[2], major = columns[3], classification = columns[4] }); 
                    }
                }
            }
            catch(Exception e)
            {
                Console.WriteLine("The file could not be read:");
                Console.WriteLine(e.Message);
            }

            sort.ItemsSource = user;
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {

        }
    }
}

Please help!请帮忙! Thank you very much!非常感谢!

You won't be able to access your Window1's DataGrid from Window2 directly.您将无法直接从 Window2 访问 Window1 的 DataGrid。 You also not have access to your source collection (List) from Window2 to modify it from there.您也无法从 Window2 访问您的源集合(列表)以从那里修改它。

In that facts, you got 2 ways:在那个事实中,你有两种方法:

  • use external database;使用外部数据库;
  • create public fixed collection of Students.创建学生的公共固定集合。

First of all and in any way I strongly recommend you to add some ID field to your Student object to be able unify each student.首先,无论如何我强烈建议您向您的Student object 添加一些ID字段,以便能够统一每个学生。

If use external database , you can simply call something like "UPDATE students s SET s.name = @name, s.age = @age... WHERE s.ID = @id" from your Window2 when Save button clicked.如果使用external database ,您可以在单击Save按钮时从Window2中简单地调用类似"UPDATE students s SET s.name = @name, s.age = @age... WHERE s.ID = @id"的内容。 @name, @age... is new modified values @name, @age...是新的修改值

If use public fixed collection , you can access it from any part of your program.如果使用public fixed collection ,您可以从程序的任何部分访问它。 When Window2 Save button clicked, you can search for student in it by student's ID and simply edit him.点击Window2 Save 按钮后,您可以通过学生 ID 在其中搜索学生并简单地编辑他。 After Window2 closing you need just refresh DataGrid view by resetting ItemsSource. Window2关闭后,您只需通过重置 ItemsSource 来刷新 DataGrid 视图。 It may look like this:它可能看起来像这样:

Student class:学生 class:

public class Student
{
    // Need to be unique for each student
    public int ID { get; private set; }

    public string Name { get; set; }
    public int Age { get; set; }
    public string Gender { get; set; }
    public string Major { get; set; }
    public string Classification { get; set; }

    public Student(int id)
    {
        ID = id;
        Name = "SomeName";
        Age = -1;
        Gender = "Unknown";
        Major = "Unknown";
        Classification = "None";
    }
    
    // May also be overloaded with id, id+name, id+name+age, id+name+age+gender etc
    public Student(int id, string name, int age, string gender, string major, string classification)
    {
        ID = id;
        Name = name;
        Age = age;
        Gender = gender;
        Major = major;
        Classification = classification;
    }

    // If you need some kind of string representation of Student
    public override string ToString()
    {
        return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
    }
} 

Fixed and public collection class to store Students:固定和公共集合 class 存储学生:

public static class DB
{
    // Your actual Database, where Students would be stored
    private static readonly List<Student> students = new List<Student>();

    // You can get it by DB.Students from anywhere
    public static List<Student> Students { get { return students; } }

    // As I see you use a file as source for item collection.
    // You can add some Save() method to rewrite you existing
    // file with items from "database":
    // public static void Save()
    // {
    //    StringBuilder sb = new StringBuilder();
    //
    //    foreach (Student student in students)
    //    {
    //        sb.AppendLine(student.ToString());
    //    }
    //
    //    File.WriteAllText("PathToYourFile", sb.ToString());
    // }
    //
    // You should also override ToString method in Student class
    // with something like (in format you wish):
    // public override string ToString()
    // {
    //     return $"{ID},{Name},{Age},{Gender},{Major},{Classification}";
    // }
    } 
} 

Update button click handler at Window1:在 Window1 更新按钮单击处理程序:

private void ButtonUpdate_Click(object sender, RoutedEventArgs e)
{
    // There should be selected only 1 item or use dataGrid.SelectedItems[0]
    if (dataGrid.SelectedItem is Student student)
    {
        // Pass selected Student to Window2
        // where user will edit it
        Window2 w2 = new Window2(student);

        // Subscribe to Closed window to refresh DataGrid view after Student editing
        w2.Closed += (s, a) =>
        {
            // Refresh the view of DataGrid by resetting its ItemsSource property
            dataGrid.ItemsSource = null;
            dataGrid.ItemsSource = DB.Students;
        };

        // Show update window
        w2.ShowDialog();
    }
}

And some kind of Window2:还有某种Window2:

public partial class Window2 : Window
{
    // Here would be a copy of Student object from Window1 
    // with which we would manipulate in Window2
    // while editing in its fields
    private readonly Student editableStudent = null;

    public Window2(Student student)
    {
        InitializeComponent();

        // Copy student object to store it in our Window2 
        // and be able to modify it not only from Constructor
        editableStudent = student;

        // Fill Window2 fields with existing Student values
        tbName.Text = student.Name;
        tbAge.Text = student.Age.ToString();
        tbGender.Text = student.Gender;
        tbMajor.Text = student.Major;
        tbClassification.Text = student.Classification;

        // Easy "on-the-fly" subscribe to each field TextChanged handlers to check, 
        // whether some data was changed/edited or not
        // and save it to editableStudent
        tbName.TextChanged += (s, a) => 
        {
            // Comparing value in field with existing Student's value
            if (tbName.Text != student.Name) // May also check for not empty / or for min input length
            {
                // Saving new value to a copied object of our Student
                editableStudent.Name = tbName.Text;
            } 
        };
        // Don't forget to check for integer value 
        // and convert in back to int: 
        // Convert.ToInt32(tbAge.Text)/int.Parse(tbAge.Text)/int.TryParse(tbAge.Text, out int age)
        tbAge.TextChanged += (sender, args) => { /* Do same as with Name */ };
        tbGender.TextChanged += (sender, args) => { /* Do same as with Name. */  };
        tbMajor.TextChanged += (sender, args) => { /* Do same as with Name */  };
        tbClassification.TextChanged += (sender, args) => { /* Do same as with Name */ };
    }

    private void ButtonSave_Click(object sender, RoutedEventArgs e)
    {
        // Find index of Student element in our "Database" (List)
        int index = DB.Students.FindIndex(x => x.ID == editableStudent.ID);

        if (index != -1)
        {
            // Update record in a collection if it was found
            DB.Students[index].Name = editableStudent.Name;
            DB.Students[index].Age = editableStudent.Age;
            DB.Students[index].Gender = editableStudent.Gender;
            DB.Students[index].Major = editableStudent.Major;
            DB.Students[index].Classification = editableStudent.Classification;

            // Instead of use 'editableStudent' field with copied in
            // constructor student's object, you can create it here
            // and fill with values from TextBoxes in Window2.
            // Or not create new Student object and fill new values
            // directly in "database" by index.
            // But you anyway need to store at least student's ID from
            // student's object, passed from Window1, to be able to 
            // find him in "database"
            // Student modifiedStudent = new Student(...);
            // modifiedStudent.Name = tbName.Text;
            // if (int.TryParse(tbAge.Text, out int age))
            //     modifiedStudent.Age = age;
            // ... 
            // DB.Students[index].Name = modifiedStudent.Name;
            // DB.Students[index].Age = modifiedStudent.Age;   
            // ...
            // or
            // DB.Students[index].Name = tbName.Text;
            // if (int.TryParse(tbAge.Text, out int age))
            //     DB.Students[index].Age = age;
            // ...         
        }
        else
        {
            // Or message user if not found
            MessageBox.Show("Student not found in Database (in a List of Students).");
        }

        // Close window after updating record in "Database"
        // DataGrid view we will refresh from Window1 after
        // Window2 close
        Close();
    }

    private void ButtonCancel_Click(object sender, RoutedEventArgs e)
    {
        // Do nothing with Student, just close
        Close();
    }
}

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

相关问题 C#WPF-如何在按下按钮时更改文本块 - C# WPF - How to change a textblock when you press a button 如何在C#WPF代码中更改\\设置按钮的背景图像? - How to change\set background image of a button in C# WPF code? C#WPF如何将内容更改为随机按钮? - C# WPF How do i change the content to a random button? 通过单击来设置和更改按钮图像WPF,C# - Set and Change Button Image by Cliciking on it WPF, C# 在C#,WPF中,如何将基于sqlite数据库的datagrid中存储在数据库中的值设置/分配给复选框 - in c#, wpf, how do you set/assign value stored in database to a checkbox in datagrid based in sqlite database WPF c#从同一数据模板中的按钮检索列表框行的内容 - WPF c# Retrieving a listbox row's contents from a button in the same datatemplate 如何创建在用户设置的特定日期和时间弹出的WPF C#应用程序? - How do I create a WPF C# Application that pops up at a certain date and time set by the user? 如何使用官方 c# 驱动程序使用 MongoDB 中的 Update.Set 更新多个字段? - How do you update multiple field using Update.Set in MongoDB using official c# driver? 在C#中,如何输出Dictionary类的内容? - In C#, how do you output the contents of a Dictionary class? WPF C#如何在另一个UserControl中的一个UserControl中更改按钮的文本? - WPF C# How do i change the Text of a Button that is in a UserControl in another UserControl?
 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM