c # winforms - изменение значения массива не работает - PullRequest
1 голос
/ 19 октября 2011

В классе form1 у меня есть:

public Color Btn1Color
{
  get { return btn1.BackColor; }
  set { btn1.BackColor = value; }
}

В классе Model у меня есть:

private Color[,] clr = new Color[50, 50];
clr[0, 0] = form1.btn1Color;
clr[0, 0] = Color.Aqua; //the color of my button does not visually change.
//But if i instead use this line it does visually change:
//form1.btn1Color = Color.Aqua;

Почему не работает первый способ (просто установка элемента массива)?Существует ли ограничение C # для установки свойств формы из массива?

Ответы [ 4 ]

4 голосов
/ 19 октября 2011

Color - это структура в C #, которая копируется во время присвоений.Это означает, что при назначении:

clr[0,0] = form1.btn1Color;

Назначается копия значения form1.btn1Color для clr[0,0].Таким образом, когда вы говорите:

clr[0,0] = Color.Aqua;

Вы перезаписываете копию, а не оригинал.

На самом деле, даже если Color было бы class вместо struct, результат был бы таким же, потому что в этом случае вы перезаписали бы ссылку.

Если выЕсли вы хотите присвоить массив для изменения исходного объекта, вам нужно будет обернуть объект в массиве для обращения к исходному объекту, в котором содержится член, содержащий Color, поскольку Color является неизменным struct.

Обновление : основываясь на вашем последующем вопросе, одна вещь, которую вы могли бы сделать (есть много способов сделать это), это обернуть Color в оболочкукласс и использовать эту оболочку для массива и в качестве члена в form1, а также:

    public class ColorHolder
    {
        // construct ColorHolder from Color
        public ColorHolder(Color color)
        {
            Current = color;
        }

        // can assign ColorHolder to Color with implicit conversion
        public static implicit operator Color(ColorHolder value)
        {
            return value.Current;
        }

        // get or set current color
        public Color Current { get; set; }
    }

Затем измените form1.btn1Color на ColorHelper вместо Color, и это работает:

        ColorHolder[,] clr = new ColorHolder[50, 50];

        // sets current color of btn1Color to black.
        form1.btn1Color = new ColorHolder(Color.Black);

        // assign array location to the color holder
        clr[0, 0] = form1.btn1Color;

        // this changes the current color of form1's btn1Color
        clr[0, 0].Current = Color.Aqua;

Примечание : Вы могли бы также разрешить преобразование из Color -> ColorHolder, но это может привести к сложному отслеживаниюошибки, поскольку это позволило бы:

        clr[0,0] = Color.Aqua;

Что бы назначить новый ColorHolder вместо изменения существующегоиспользуя Current.Таким образом, я бы избежал преобразования Color -> ColorHolder и придерживался чего-то подобного выше.

Вы можете даже обобщить этот код Holder для поддержки любого типа, например:

    public class Holder<T>
    {
        public Holder(T value)
        {
            Value = value;
        }

        public static implicit operator T(Holder<T> holder)
        {
            return holder.Value;
        }

        public T Value { get; set; }
    }

Тогда вместо ColorHolder вы получите Holder<Color> или любой другой тип.Опять же, это будет использоваться следующим образом (при условии, что form1 s btn1Color member теперь Holder<Color>):

        Holder<Color>[,] clr = new Holder<Color>[50, 50];

        form1.btn1Color = new Holder<Color>(Color.Black);

        clr[0, 0] = form1.btn1Color;

        // sets the Color in form1.btn1Color to Aqua...
        clr[0, 0].Value = Color.Aqua;
1 голос
/ 19 октября 2011

Свойства и переменные назначаются справа налево.Чтобы присвоить значение form.btn1Color, вам необходимо присвоить значение, подобное этому:

form1.btn1Color = clr[0, 0];

Вызов clr[0, 0] = form1.btn1Color; сохраняет только цвет в массиве, и ничего больше.Он не помнит сам объект.

1 голос
/ 19 октября 2011

Я думаю, что вместо этого вы хотели

clr[0, 0] = Color.Aqua;
form1.btn1Color = clr[0, 0] ;
1 голос
/ 19 октября 2011

clr[0,0] = form1.btn1Color; присваивает массиву текущее значение цвета кнопки.

Как только это будет сделано, связь между свойством Color кнопки и массивом не будет. Это значение цвета, помещенного в массив, а не ссылка на цвет фона кнопки.

Если вы действительно хотите установить цвета кнопок через массив таким образом, сохраните массив кнопок и обратитесь к свойству BackColor при установке цвета.

Добро пожаловать на сайт PullRequest, где вы можете задавать вопросы и получать ответы от других членов сообщества.
...