以编程方式添加多个扩展器事件将无法工作

时间:2012-02-24 10:50:41

标签: c# wpf events expander

我在向Expanders添加Expanded事件时遇到了问题。我在我的窗口上有扩展器,我希望在扩展扩展器时获得效果,其他所有扩展器都将停止运行。我写的功能让我这样做,它的工作正确。问题是我有96个扩展器,我不想为Expand添加96个事件,为崩溃添加96个事件,所以我认为我可以通过编程方式添加它。

查看代码:

    private void InitExpanders()
    {
        var expanders = GetExpanders(); // List<Expander> - list of expanders
        for (int i = 0; i < expanders.Count; i++)
        {
            if (i % 6 == 1)
            {
                    expanders[i - 1].Expanded += new RoutedEventHandler(delegate(object sender, RoutedEventArgs args)
                    {
                        DisableBigExpanders(1); // problem is here!
                    });
            }
        }
    }

此代码工作正常但对于每个扩展器函数参数将为1。 我试图添加整数并增加它但它不会工作。

    private void InitExpanders()
    {
        var expanders = GetExpanders();
        int x = 0;
        for (int i = 0; i < expanders.Count; i++)
        {
            if (i % 6 == 1)
            {
                    expanders[i - 1].Expanded += new RoutedEventHandler(delegate(object sender, RoutedEventArgs args)
                    {
                        DisableBigExpanders(x);
                    });
                    x++;
            }
        }
    }

感谢所有回复。

1 个答案:

答案 0 :(得分:2)

我怀疑你发现委托中的x始终是循环期间达到的最高值。这是由于编译器实例化您定义的匿名方法的实例的方式。它查看了委托周围捕获的外部变量的内容,并确定它是否需要单独的实例,或者它是否可以使用单个实例。在这种情况下,您没有捕获的外部变量;因此,允许编译器使用委托的相同实例,因此使用相同的x。

要解决此问题,您需要做的就是在委托之前添加一个更细粒度的变量,并为其赋值x。这将有效:

private void InitExpanders()
{
    var expanders = GetExpanders();
    int x = 0;
    for (int i = 0; i < expanders.Count; i++)
    {
        if (i % 6 == 1)
        {
                int y = x++;
                expanders[i - 1].Expanded += delegate
                {
                    DisableBigExpanders(y);
                };
        }
    }
}

有关理论的更多信息,请参阅此处:http://en.csharp-online.net/ECMA-334%3A_14.5.15.4_Anonymous_method_evaluation