表单关闭时保存控件状态

时间:2013-03-04 00:58:27

标签: c# xml winforms state

您好我正在尝试将使用2D数组动态创建的4x4网格按钮的颜色状态保存到xml文档中:

enter image description here

然而,当我按下保存时,我不断收到此消息:

如果我使用一维数组作为按钮但是这不会给我想要的网格,但是当我使用2D数组作为按钮它不会工作时,我可以使这个工作:

enter image description here

我可以改变什么,所以我可以让这个工作任何建议非常感谢:

这是我的代码:

FormState上课:

public class FormState
{
    public string ButtonBackColor { get; set; }
}

表格代码:

public partial class Form1 : Form
{
        int col = 4;
        int row = 4;
        Button[,] buttons;
        FormState[,] states;
        public Form1()
        {
            InitializeComponent();
            buttons = new Button[col, row];
            states = new FormState[col, row];
        }

        public void placeRows()
        {
            for (int r = 0; r < row; r++)
            {
                createColumns(r);
            }
        }

        public void createColumns(int r)
        {
            int s = r * 25; //gap
            for (int c = 0; c < col; c++)
            {
                buttons[r, c] = new Button();
                buttons[r, c].SetBounds(75 * c, s, 75, 25);
                buttons[r, c].Text = Convert.ToString(c);
                buttons[r, c].Click += new EventHandler(grid_Click);
                panel1.Controls.Add(buttons[r, c]);
            }
        }

        int count = 0;
        //backcolor change
        void grid_Click(object sender, EventArgs e)
        {
            Button button = sender as Button;

            if (count == 0)
            {
                button.BackColor = Color.Red;
                count++;
            }

            else if (count == 1)
            {
                button.BackColor = Color.Blue;
                count--;
            }
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            placeRows();

            if (File.Exists("config.xml"))
            {
                loadConfig();
            }

            for (int i = 0; i < col; ++i)
            {
                for (int j = 0; j < row; ++j)
                {
                    if (states[i,j] != null)
                    {
                        buttons[i,j].BackColor = ColorTranslator.FromHtml(states[i,j].ButtonBackColor);
                    }
                }
            }
        }

        //method to load file
        private void loadConfig()
        {
            XmlSerializer ser = new XmlSerializer(typeof(FormState[]));
            using (FileStream fs = File.OpenRead("config.xml"))
            {
                states = (FormState[,])ser.Deserialize(fs);
            }
        }

        private void writeConfig()
        {
            for (int i = 0; i < col; i++)
            {
                for (int j = 0; j < row; j++)
                {
                    if (states[i,j] == null)
                    {
                        states[i,j] = new FormState();
                    }
                    states[i,j].ButtonBackColor = ColorTranslator.ToHtml(buttons[i,j].BackColor);
                }

                using (StreamWriter sw = new StreamWriter("config.xml"))
                {
                    XmlSerializer ser = new XmlSerializer(typeof(FormState[]));
                    ser.Serialize(sw, states);
                }
            }
        }

        private void btnSave_Click(object sender, EventArgs e)
        {
            writeConfig();
        }
    }

2 个答案:

答案 0 :(得分:1)

这可能不是一个理想的解决方案(我没有尝试过,所以它甚至可能无法工作),但你可以创建一个嵌套数组而不是二维数组。像

这样的东西
FormStates[][] states = new FormStates[row][];
for(Int32 i = 0; i < row; i++)
{
    states[i] = new FormStates[col];
}

您可以使用states[i, j],而不是使用states[i][j]建立索引。由于1-D数组是可序列化的,因此可能会有效。

修改

稍长一些示例,基于您的代码:

public partial class Form1 : Form
{
    int col = 4;
    int row = 4;
    Button[][] buttons;
    FormState[][] states;
    public Form1()
    {
        InitializeComponent();
        buttons = new Button[col][];
        states = new FormState[col][];
        for(Int32 c = 0; c < col; c++)
        {
            buttons[c] = new Button[row];
            states[c] = new FormState[row];
        }
    }

    public void createColumns(int r)
    {
        int s = r * 25; //gap
        for (int c = 0; c < col; c++)
        {
            buttons[r][c] = new Button();
            buttons[r][c].SetBounds(75 * c, s, 75, 25);
            buttons[r][c].Text = Convert.ToString(c);
            buttons[r][c].Click += new EventHandler(grid_Click);
            panel1.Controls.Add(buttons[r][c]);
        }
    }
}

这应该足以为您提供更改代码其余部分的语法。

您还需要将XmlSerializer声明更改为使用typeof(FormState[][]),而不仅仅是typeof(FormState[])

答案 1 :(得分:0)

不可否认,我没有多想过这个但是根据评论你不能序列化多维数组,所以你可能会:

 [Serializable]
    public class FormState
    {
        public int RowIndex { get; set; }
        public int ColIndex { get; set; }
        public string BackColor { get; set; }
    }

    [Serializable]
    public class Layout : Collection<FormState> { 

        public Layout(){}
    }

...

        public void SomeCallingMethod() {
            Layout l = new Layout();
            foreach (FormState fs in l) {
                buttons[fs.RowIndex, fs.ColIndex].BackColor = ColorTranslator.FromHtml(fs.BackColor);
            }     
        }

如果需要,可以使用List并序列化。