0

こんにちは、2D 配列を使用して動的に作成されたボタンのこの 4x4 グリッドの色の状態を xml ドキュメントに保存しようとしています。

ここに画像の説明を入力

ただし、保存を押すと、次のメッセージが表示され続けます。

ボタンに1次元配列を使用すると、これを機能させることができますが、必要なグリッドが得られませんが、ボタンに2D配列を使用すると機能しません。

ここに画像の説明を入力

これを機能させるために何を変更できますか?どんな提案でも大歓迎です:

これは私が持っている私のコードです:

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();
        }
    }
4

2 に答える 2

1

これは理想的な解決策ではないかもしれません (私は試していないので、うまくいかないかもしれません) が、2 次元配列の代わりにネストされた配列を作成することはできます。何かのようなもの

FormStates[][] states = new FormStates[row][];
for(Int32 i = 0; i < row; i++)
{
    states[i] = new FormStates[col];
}

を使用して索引付けする代わりにstates[i, j]、 を使用しますstates[i][j]。1 次元配列はシリアライズ可能であるため、これでうまくいく可能性があります。

編集

コードに基づく、少し長い例:

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[])

于 2013-03-04T03:12:43.273 に答える
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);
            }     
        }

または、必要に応じてリストを使用し、それをシリアル化します。

于 2013-03-04T02:04:44.253 に答える