0

我对 C# 编程完全陌生。(4天)

我在 Excel VB 上进行了一些业余编程,为我们的团队创建了仪表板。现在我想把它提升到一个新的水平。

我的仪表板有 10 个按钮,每次单击都会将颜色从红色变为绿色并返回。每次单击都会将其下方的标签从 Text 1 更改为 Text 2。

功能:概述完成工作并交给我们的服务区域。我为每个区域设置了 10 个不同的空白,因为我没有设法将点击的按钮链接到标签,所以我只使用了 10 个。“northwest”、“east”、“southeast”等等。

void northwest(object sender, EventArgs e)
{
    Button button = sender as Button;
    Control ctrl = ((Control)sender);
    switch (ctrl.BackColor.Name)
    {
        case "Red":
            ctrl.BackColor = Color.LimeGreen;
            ctrl.ForeColor = Color.Black;
            lbl_nw.Text = "Service";
            break;
        case "LimeGreen":
            ctrl.BackColor = Color.Red;
            ctrl.ForeColor = Color.White;
            lbl_nw.Text = "North-West";
            break;
        default:
            ctrl.BackColor = Color.LimeGreen;
            ctrl.ForeColor = Color.Black;
            lbl_nw.Text = "Service";
            break;
    }
}

第二:我有 145 个按钮(团队),每次点击都会在 5 种不同的颜色之间变化。我们用它来澄清团队的状态。比如“n/a”、“available”、“on the way”等。

void MyButtonClick(object sender, EventArgs e)
{
    Button button = sender as Button;
    Control ctrl = ((Control)sender);
    switch (ctrl.BackColor.Name)
    {
        case "Gainsboro": // switch from n/a to available
            ctrl.BackColor = Color.LimeGreen;
            ctrl.ForeColor = Color.White;
            break;
        case "LimeGreen": // switch from available to on the way
            ctrl.BackColor = Color.Yellow;
            ctrl.ForeColor = Color.Black;
            break;
        case "Yellow": // switch from on the way to fully occupied
            ctrl.BackColor = Color.Orange;
            ctrl.ForeColor = Color.Black;
            break;
        case "Orange": // switch from fully occupied to omitted
            ctrl.BackColor = Color.Red;
            ctrl.ForeColor = Color.White;
            break;
        case "Red": // switch from omitted to back at home
            ctrl.BackColor = Color.Aqua;
            ctrl.ForeColor = Color.Black;
            break;
        default:
            ctrl.BackColor = Color.Gainsboro;
            ctrl.ForeColor = Color.Black;
            break;
    }
}

现在实际问题是:因为我以前的仪表板只能由一个人使用(在一台中央计算机上),所以我想让我的新仪表板对多用户友好。所以我的意图是将颜色/标签名称保存到 txt 文件或 xml 文件中(忘记 xml。它对我来说太复杂了)并在任何用户对板上有任何更改时自动加载它。

我搜索但找不到我真正理解的任何解决方案(因为缺少知识)。

我尝试了以下方法:

void save(object sender, EventArgs e)
{
    TextWriter txt = new StreamWriter("C:\\Users\\shift.txt");              

    txt.Write(button1.Text);
    txt.Write(button1.ForeColor);
    txt.Write(button1.BackColor);
    txt.Close();
}

在这个解决方案中,我需要编写我想要存储的每个按钮。问题:我得到这样的东西: North-West Color [LimeGreen] Color [Black]

我认为正确的解决方案是这样North-West;LimeGreen;Black,但我不知道怎么做!即使那样我也不知道如何将所有值加载回正确的对象。

我试图通过它们循环:

for (int i = 1; i < 155; i++)

但是我遇到了每个组合的对象问题(例如“是一种类型但用作方法”)。

第二次尝试是通过 xml。但这对我来说太复杂了。我试过这样:

void savedata(object sender, EventArgs e)
{
    DataSet d = new DataSet();
    DataTable t = new DataTable();

    d.Tables.Add(t);
    t.Columns.Add(new DataColumn("Name",typeof(string)));
    t.Columns.Add(new DataColumn("FontColor",typeof(string)));
    t.Columns.Add(new DataColumn("Background",typeof(string)));                 
    t.Rows.Add(button6.Text, button6.ForeColor, button6.BackColor);
    t.Rows.Add(button7.Text, button7.ForeColor, button7.BackColor);
    t.Rows.Add(button8.Text, button8.ForeColor, button8.BackColor);
    t.Rows.Add(button9.Text, button9.ForeColor, button9.BackColor);
    t.Rows.Add(button10.Text, button10.ForeColor, button10.BackColor);
    t.Rows.Add(button11.Text, button11.ForeColor, button11.BackColor);
    t.Rows.Add(button12.Text, button12.ForeColor, button12.BackColor);
    t.Rows.Add(button13.Text, button13.ForeColor, button13.BackColor);
    t.Rows.Add(button14.Text, button14.ForeColor, button14.BackColor);
    t.Rows.Add(button15.Text, button15.ForeColor, button15.BackColor);
    d.WriteXml("C:\\Users\\Shift.xml");
}

它可以保存,是的,但是我如何将它加载回正确的对象中?我对反序列化一无所知,我只是阅读了一些代码并尝试采用它并失败了。

我的问题:

有没有人对如何正确保存/加载/格式化文本文件有适当的解决方案?如果有新的更改,则应进行保存,加载也是如此。如此自动。每个用户都可以打开仪表板,文件存储将在我们的服务器上,每个人都可以访问它以通过仪表板保存/加载它。

我真的很感激一个可能的解决方案。就像我说的,我是一个初学者,这个问题让我发疯。

一切正常,除了保存/加载机制。

顺便提一下:我不能下载任何其他软件,所以我需要坚持使用 Windows 程序。

4

1 回答 1

0

for saving and loading from a flat file (.txt, .xml, .json, .whatver) I use the following solution, it's honestly very easy and takes the hard work away. You will need to download and install NewtonSoft package from nuget. But trust me it makes everything easy.

Let's create a hypothetical scenario similar to yours. You have many users and want to save information for each of them. Let's start with a user class.

public class User {
    public int Id { get; set; }
    public string Name { get; set; }
    public string Theme { get; set; }
}

Now lets create a little 'database' or 'data holder' class that will actually store and lookup our info. It will have a FilePath variable where we will save our flat file, a List of all the Users and some functions to help get everything:

public static class DataHolder {
        
        public static string FilePath { get; set; }
        public static List<Users> Users { get; set; }
        
        static DataHolder() 
        {
            // Initialize the variables
            FilePath = "C:/Temp/MyData.json";
            Users = new List<User>();
            Init();
        }
        
        static void Init() { }
        
        public static void LoadData() { }
        
        public static void SaveData() { }
}

Let's start by creating a file to save all the data in.

using System.IO;
using NewtonSoft;
...

static void Init() { 
    // Check if file exists
    if (File.Exist(FilePath))
    {
        LoadData();
        return;
    }
        
    // It doesn't so we create it
    using (var sw = new StreamWriter(FilePath)){
        
        // Create empty list of users
        var emptyUserList = new List<User>();
        
        // Convert it into Json using NewtonSoft 
        var fileText = JsonConvert.SerializeObject(emptyUserList);
        
        // Write it to the file
        sw.Write(fileText);
    }
}

Above we used Newton to create a new file with an empty Json object in it. Let's see how loading and saving will work:

public static void LoadData() {         
    using (var sr = new StreamReader(FilePath)){
        Users = JsonConvert.Deserialize<List<User>>(sr.ReadToEnd());
    }               
}
        
public static void SaveData() {
    using (var sw = new StreamReader(FilePath)){
        sw.Write(JsonConvert.Serialize(Users));
    }
}

And that is the main bulk of the class. Let's implement a GetUser() and AddUser() function that searches for a user based on Id and then I'll show you an example of how to use the class:

    using System.Linq;   
    ...

    public static User GetUser(int id) => Users.FirstOrDefault(x => x.Id = id);
        
    public static void AddUser(User user) => Users.Add(user);

Example:

public static void Main(string[] args){
    
    // Test the saving
    TestSaving();
    
    // Test the loading
    TestLoading();
    
}

static void TestLoading() { 
    // Get a user
    var loadedUser = DataHolder.GetUser(1);
    
    if (loadedUser != null)
        Console.WriteLine("Success");
    
    
}
static void TestSaving() {
    // Create a new user and add it
    var user = new User() {
        Id = 1,
        Name = "Fred",
        Theme = "Red"
    };
    
    // Save the data in memory
    DataHolder.AddUser(user);
    
    // Save the data to file
    DataHolder.SaveData();
}
于 2021-01-21T04:59:07.820 回答