c#winforms - 更改数组的值不起作用

时间:2011-10-19 13:46:06

标签: c# .net winforms visual-studio visual-studio-2010

在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 个答案:

答案 0 :(得分:4)

Color是C#中的结构,在分配期间复制。这意味着当你指定:

clr[0,0] = form1.btn1Color;

它会将form1.btn1Color的值分配给clr[0,0]。因此,当你说:

clr[0,0] = Color.Aqua;

您正在覆盖副本,而不是原始副本。

事实上,即使Colorclass而不是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的{​​{1}}成员现在是btn1Color):

Holder<Color>

答案 1 :(得分:1)

clr[0,0] = form1.btn1Color;将按钮颜色的当前分配给数组。

完成此操作后,按钮的Color属性与数组之间没有任何关系。它是放入数组的颜色的,而不是对按钮背景颜色的引用。

如果您真的想以这种方式通过数组设置按钮颜色,请存储一组按钮并在设置颜色时引用BackColor属性。

答案 2 :(得分:1)

我认为你想要做的是

clr[0, 0] = Color.Aqua;
form1.btn1Color = clr[0, 0] ;

答案 3 :(得分:1)

属性和变量从右到左分配。要为form.btn1Color指定值,您需要指定如下值:

form1.btn1Color = clr[0, 0];

调用clr[0, 0] = form1.btn1Color;仅将颜色存储在数组中,没有别的。它不记得对象本身。