C# 为什么可以';我不能从事件处理程序中访问变量吗?

C# 为什么可以';我不能从事件处理程序中访问变量吗?,c#,wpf,event-handling,C#,Wpf,Event Handling,我正在做一个项目,我用Visual Studio上的C#创建了整个项目(包括模板) 我已经制作了模板,并且刚刚开始处理事件,我想为我创建的画布制作一个事件MouseLeftButtonDown,这个事件将记录鼠标位置 这是我的代码: public partial class MainWindow : Window { public MainWindow() { InitializeComponent(); }

我正在做一个项目,我用Visual Studio上的C#创建了整个项目(包括模板)

我已经制作了模板,并且刚刚开始处理事件,我想为我创建的画布制作一个事件MouseLeftButtonDown,这个事件将记录鼠标位置

这是我的代码:

 public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private char tester;
        private Point down1;
        private Point up1;

        private void Grid1_Loaded(object sender, RoutedEventArgs e)
        {
            RowDefinition row1 = new RowDefinition();
            RowDefinition row2 = new RowDefinition();

            row1.Height = new GridLength(40);
            row2.Height = new GridLength(1, GridUnitType.Star);

            Grid1.RowDefinitions.Add(row1);
            Grid1.RowDefinitions.Add(row2);

            Canvas canvas1 = new Canvas();
            canvas1.Background = new SolidColorBrush(Colors.Beige);
            Grid.SetRow(canvas1, 1);
            Grid1.Children.Add(canvas1);
            canvas1.MouseLeftButtonDown += new RoutedEventHandler(canvas1_MouseLeftButtonDown);
            canvas1.MouseLeftButtonUp += new RoutedEventHandler(canvas1_MouseLeftButtonUp);


            Button btnRect = new Button();
            btnRect.Content = "Rectangulo";
            btnRect.Margin = new Thickness(5, 5, 5, 5);
            btnRect.HorizontalAlignment = HorizontalAlignment.Left;
            btnRect.VerticalAlignment = VerticalAlignment.Center;
            Grid.SetRow(btnRect, 0);
            Grid1.Children.Add(btnRect);
            //btnRect.Click += new RoutedEventHandler(btnRect_Click);

            Button btnEllip = new Button();
            btnEllip.Content = "Ellipse";
            btnEllip.Margin = new Thickness(75, 5, 5, 5);
            btnEllip.HorizontalAlignment = HorizontalAlignment.Left;
            btnEllip.VerticalAlignment = VerticalAlignment.Center;
            Grid.SetRow(btnEllip, 0);
            Grid1.Children.Add(btnEllip);
            //btnEllip.Click += new RoutedEventHandler(btnEllip_Click);

        }
这是我的活动:

private void canvas1_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
            {
                 down1 = e.GetPosition(canvas1); 
            }
        }
    }
我试过做
down1=e.GetPosition(canvas1)但我在(canvas1)上出错;“canvas1名称在当前上下文中不存在”


我做了一个类似的项目,无需编写模板,没有任何问题。

您在Grid1_加载的方法中将
canvas1
声明为局部变量。在类中将其定义为成员变量,它应该可以工作。

如何:

down1 = e.GetPosition((Canvas)sender); 

问题是canvas1是Grid1_中的一个局部变量。无法在该方法之外访问该变量。

问题在于
canvas1
不在范围内。您可以内联一个简单的lambda表达式,如下所示:

canvas1.MouseLeftButtonDown += (sender, e) => down1 = e.GetPosition(canvas1);
但我在(画布1)上出错了

这是因为
canvas1
是另一个方法的局部变量,在
canvas1\u MouseLeftButtonDown()中无法访问

您可以使用:

 Canvas c = sender as Canvas;  // or Canvas c = (Canvas) sender;
 down1 = e.GetPosition(c); 

我会使用转换的
作为
,这样您就可以避免相当烦人的
NullReferenceException
@Chaos:只是为了用它换取一个
InvalidCastException
?我认为这不重要,我觉得
as
更容易阅读。我更喜欢
InvalidCastException
,因为它提供了更多的信息。以防有人将同一个处理程序重新用于另一个控件。(我知道这个具体的例子并不重要,但我仍然认为这是一个很好的做法。)@Chaos:没错,但在这种情况下,我仍然会使用更具可读性的形式。太棒了。令人惊讶的是,我是如何爱上这些东西的。非常感谢。