[英]c# winforms - changing value of array doesn't work
In form1 class I have: 在form1类中,我有:
public Color Btn1Color
{
get { return btn1.BackColor; }
set { btn1.BackColor = value; }
}
In the Model class I have: 在模型类中,我有:
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;
Why doesn't the first way (just setting the array element) work? 为什么第一种方法(仅设置数组元素)不起作用? Is there a C# limitation of setting form properties from an array?
从数组设置表单属性有C#限制吗?
Color
is a structure in C#, which is copied during assignments. Color
是C#中的一种结构,在分配过程中会被复制。 That means when you assign: 这意味着您分配:
clr[0,0] = form1.btn1Color;
It assigns a copy of the value of form1.btn1Color
to clr[0,0]
. 它将
form1.btn1Color
值的副本分配给clr[0,0]
。 Thus, when you then say: 因此,当您然后说:
clr[0,0] = Color.Aqua;
You are overwriting the copy, not the original. 您将覆盖副本,而不是原始副本。
In fact, even if Color
were a class
instead of struct
the result would be the same, because in that case you'd overwrite the reference. 实际上,即使
Color
是class
而不是struct
,结果也一样,因为在这种情况下,您将覆盖引用。
If you wanted assigning the array to modify the original object, you would need to wrap the object in the array to refer back to the original object that has the member holding the Color
, since Color
is an immutable struct
. 如果要分配数组以修改原始对象,则需要将对象包装在数组中,以引用具有持有
Color
成员的原始对象,因为Color
是不可变的struct
。
Update : based on your follow up question, one thing you could do (there are really many ways to do this) is to wrap the Color
in a wrapper class, and use that wrapper for the array and as the member in form1
as well: 更新 :根据您的后续问题,您可以做的一件事(确实有很多方法可以做到)是将
Color
包装在wrapper类中,并将该包装用于数组以及作为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; }
}
Then, change form1.btn1Color
to be ColorHelper
instead of Color
and this works: 然后,将
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;
Note : You could also allow a conversion from Color
-> ColorHolder
as well, but this could lead to hard-to-track bugs as it would allow: 注意 :您还可以允许从转换
Color
- > ColorHolder
为好,但是这可能会导致难以跟踪的错误,因为它能够:
clr[0,0] = Color.Aqua;
Which would assign a new ColorHolder
instead of changing the existing using Current
. 这将分配一个新的
ColorHolder
而不是使用Current
来更改现有的ColorHolder
。 Thus I'd avoid the Color
-> ColorHolder
conversion and stick with something like the above. 因此,我会避免
Color
- > ColorHolder
转换并且用类似上面沾。
You could even generalize this Holder
code to support any type, like: 您甚至可以泛化此
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; }
}
Then instead of ColorHolder
you'd have Holder<Color>
or any other type. 然后,您将拥有
Holder<Color>
或任何其他类型,而不是ColorHolder
。 Again, this would be used like the following (assuming form1
's btn1Color
member is now Holder<Color>
): 再次,它的用法如下(假设
form1
的btn1Color
成员现在为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;
clr[0,0] = form1.btn1Color;
assigns the current value of the button's colour to the array. 将按钮颜色的当前值分配给数组。
Once this is done there is no relationship between the button's Color property and the array. 完成此操作后,按钮的Color属性与数组之间就没有关系。 It's the value of the colour that's put into the array, not the reference to the button's background colour.
这是放入数组的颜色值 ,而不是按钮背景色的引用。
If you really want to set button colours through an array in this way, store an array of buttons and reference the BackColor property when you set the colour. 如果您确实想以这种方式通过数组设置按钮颜色,请存储按钮数组并在设置颜色时引用BackColor属性。
I think what you wanted to do instead was to 我想你想做的是
clr[0, 0] = Color.Aqua;
form1.btn1Color = clr[0, 0] ;
Properties and Variables are assigned from right to left. 属性和变量从右到左分配。 To assign a value to
form.btn1Color
, you need to assign a value like this: 要将值分配给
form.btn1Color
,您需要分配一个值,如下所示:
form1.btn1Color = clr[0, 0];
Calling clr[0, 0] = form1.btn1Color;
调用
clr[0, 0] = form1.btn1Color;
only stores the color in the array, nothing else. 仅将颜色存储在数组中,仅此而已。 It does not remember the object itself.
它不记得对象本身。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.