繁体   English   中英

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

[英]c# winforms - changing value of array doesn't work

在form1类中,我有:

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

在模型类中,我有:

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#限制吗?

Color是C#中的一种结构,在分配过程中会被复制。 这意味着您分配:

clr[0,0] = form1.btn1Color;

它将form1.btn1Color值的副本分配给clr[0,0] 因此,当您然后说:

clr[0,0] = Color.Aqua;

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

实际上,即使Colorclass而不是struct ,结果也一样,因为在这种情况下,您将覆盖引用。

如果要分配数组以修改原始对象,则需要将对象包装在数组中,以引用具有持有Color成员的原始对象,因为Color是不可变的struct

更新 :根据您的后续问题,您可以做的一件事(确实有很多方法可以做到)是将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; }
    }

然后,将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来更改现有的ColorHolder 因此,我会避免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; }
    }

然后,您将拥有Holder<Color>或任何其他类型,而不是ColorHolder 再次,它的用法如下(假设form1btn1Color成员现在为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; 将按钮颜色的当前分配给数组。

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

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

我想你想做的是

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

属性和变量从右到左分配。 要将值分配给form.btn1Color ,您需要分配一个值,如下所示:

form1.btn1Color = clr[0, 0];

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

暂无
暂无

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM