C#标签控件无法正常工作

时间:2013-09-12 13:31:04

标签: c# label

当我运行以下代码时,它会填充label1控件一次。然后label1控件不执行任何操作。如何让label1控件更改鼠标输入事件。请提供代码示例。

    int currentXposition, currentYposition;
    const string positionLabel = "Current Position: ";

    private void Test_Load(object sender, EventArgs a)
    {
        var temp=Color.Transparent;    //Used to store the old color name of the panels before mouse events
        var colorName = Color.Red;      //Color used to highlight panel when mouse over
        int numBlocks = 8;             //Used to hold the number of blocks per row
        int blockSize=70;

        //Initialize new array of Panels  new
        string[,] Position = new string[8, 8];
        Panel[,] chessBoardPanels = new Panel[numBlocks, numBlocks];
        string Alphabet = "A,B,C,D,E,F,G,H";
        string Numbers ="1,2,3,4,5,6,7,8";
        string[] alphaStrings = Alphabet.Split(',');
        string[] numStrings=Numbers.Split(',');
        // b = sub[0];
        int FirstValue, SecondValue;

        //Store Position Values
        for (int firstValue = 0; firstValue < 8; ++firstValue)
        {
            FirstValue = Alphabet[firstValue];
            for (int SecValue = 0; SecValue < 8; ++SecValue)
            {
                SecondValue = Numbers[SecValue];
                Position[firstValue, SecValue] = alphaStrings[firstValue] + numStrings[SecValue];
            }
        }

        //Loop to create panels
        for (int iRow = 0; iRow < numBlocks; iRow++)
        {
            for (int iColumn = 0; iColumn < numBlocks; iColumn++)
            {
                Panel p = new Panel();
                //set size
                p.Size = new Size(blockSize, blockSize);
                //set back colour
                p.BackColor = (iRow + (iColumn % 2)) % 2 == 0 ? Color.Black : Color.White;
                //set location
                p.Location = new Point(blockSize *iRow+15, blockSize * iColumn+15);
                chessBoardPanels[iRow, iColumn] = p;
                chessBoardPanels[iRow,iColumn].MouseEnter += (s,e) =>
                {
                    currentXposition = iRow;
                    currentYposition = iColumn;

                    var oldColor = (s as Panel).BackColor;
                    (s as Panel).BackColor = colorName;
                    temp = oldColor;
                    label1.Text = Position[iRow, iColumn];
                };

                chessBoardPanels[iRow, iColumn].MouseLeave += (s, e) => {
                    (s as Panel).BackColor = temp;
                };
                groupBox1.Controls.Add(p);
            }
        }
    }

1 个答案:

答案 0 :(得分:0)

我之所以回答这个问题只是因为我认为展示范围混淆时会发生什么很重要。您遇到问题的原因是变量的范围。您的标签正在更改iRow * iColumn次,但仅限于初始执行期间。从那时起,iRowiColumn将固定为最终值。

要实现您期望的最终目标,最简单的方法是创建Panel的扩展:

public class ChessPanel : Panel {

     private const Color HighlightColor = Color.Red;


     public int iColumn { get; set; }
     public int iRow { get; set; }
     public Color PrimaryColor { get; set; }

     public ChessPanel() : base()
     {
        this.MouseEnter += (s,e) =>
                {
                    this.PrimaryColor = this.BackColor;
                    this.BackColor = HighlightColor;
                };

         this.MouseLeave += (s,e) => 
                {
                    this.BackColor = this.PrimaryColor;
                };
     }     

}    

这将允许您按如下方式减少代码:

int currentXposition, currentYposition;
const string positionLabel = "Current Position: ";

private void Test_Load(object sender, EventArgs a)
{
    var temp=Color.Transparent;    //Used to store the old color name of the panels before mouse events
    var colorName = Color.Red;      //Color used to highlight panel when mouse over
    int numBlocks = 8;             //Used to hold the number of blocks per row
    int blockSize=70;

    //Initialize new array of Panels  new
    string[,] Position = new string[8, 8];
    ChessPanel[,] chessBoardPanels = new ChessPanel[numBlocks, numBlocks];
    string Alphabet = "A,B,C,D,E,F,G,H";
    string Numbers ="1,2,3,4,5,6,7,8";
    string[] alphaStrings = Alphabet.Split(',');
    string[] numStrings=Numbers.Split(',');
    int FirstValue, SecondValue;

    //Store Position Values --- no idea what this is supposed to do...
    for (int firstValue = 0; firstValue < 8; ++firstValue)
    {
        FirstValue = Alphabet[firstValue];
        for (int SecValue = 0; SecValue < 8; ++SecValue)
        {
            SecondValue = Numbers[SecValue];
            Position[firstValue, SecValue] = alphaStrings[firstValue] + numStrings[SecValue];
        }
    }

    //Loop to create panels
    for (int iRow = 0; iRow < numBlocks; iRow++)
    {
        for (int iColumn = 0; iColumn < numBlocks; iColumn++)
        {
            ChessPanel p = new ChessPanel();
            //set size
            p.Size = new Size(blockSize, blockSize);
            //set back colour
            p.BackColor = (iRow + (iColumn % 2)) % 2 == 0 ? Color.Black : Color.White;
            //set location
            p.Location = new Point(blockSize *iRow+15, blockSize * iColumn+15);

            p.MouseEnter += (s,e) =>
            {
                var cpSelf = s as ChessPanel;
                if (cpSelf != null)
                {
                    label1.Text = Position[cpSelf.iRow, cpSelf.iColumn];
                }
            };

            groupBox1.Controls.Add(p);
            chessBoardPanels[iRow, iColumn] = p;
        }
    }
}

我假设你后来在程序中使用了很多这些变量,看着这种情况会让我头疼,所以我把它的大部分留在原地。

代理是一个非常强大且有用的实用程序,但它们可能会导致与变量范围混淆。使用它们时要非常小心,并确保将它们视为稍后执行的功能单元,因此只能在执行块时而不是在创建块时依赖程序的状态。如果你注意到,我保留了对Position数组的引用,只是为了表明你仍然可以访问委托范围内的局部变量,因为它在技术上仍然在范围内。在结构上,这可以很容易地移动到ChessPanel类中并在本地引用100%。这个例子应该用作一个注意事项,因为它可以显示许多人假设在功能执行结束时被垃圾收集的“本地”变量如何可以徘徊并消耗内存。

此代码未经测试,可能会出现轻微的语法错误。希望结构精神得到理解。