在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#限制?
答案 0 :(得分:4)
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
的{{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;
仅将颜色存储在数组中,没有别的。它不记得对象本身。