3

我只是有一个关于实例变量放置的小问题。

例子:

private void example_MouseMove(object sender, MouseEventArgs e){
    //do stuff
}

c# 中的鼠标移动事件一直在轮询。有时我可能只想在鼠标位置完全移动到另一个像素时才运行其中的代码。所以我会写这个:

private void example_MouseMove(object sender, MouseEventArgs e){
    if (_prevMousePosition == Cursor.Position) return;
    //Do stuff
}

我的问题是:变量“_prevMousePosition”是否像往常一样位于类的顶部,还是直接位于方法的顶部,如下所示:

private Point _prevMousePosition = new Point(0, 0);
private void example_MouseMove(object sender, MouseEventArgs e){
    if (_prevMousePosition == Cursor.Position) return;
    //Do stuff
}

我觉得它应该位于方法之上,因为唯一可以访问它的地方是事件,并且它在方法之外的唯一目的是保留以前的鼠标位置。

另外,如果有另一种方法可以在没有实例变量的情况下实现相同的功能,我很想知道。

4

4 回答 4

7

我的问题是:变量“_prevMousePosition”是像往常一样位于类的顶部,还是直接位于方法的顶部,如下所示:

这纯粹是个人喜好。编译器不关心你把它放在哪里。将它放在方法之上是完全有效的 C#,不会导致任何问题。

C# 代码的最标准约定(包括由StyleCop等工具强制执行的约定)建议您将该字段与所有其他字段一起放在类的顶部。这样做的好处是您可以轻松浏览您的班级并查看所有本地存储的数据,并确保您正确初始化等。

于 2013-06-05T17:08:17.840 回答
1

尤其要警惕为单个方法保留状态的类字段。考虑:

  1. 创建一个单独的类来处理鼠标动作和保存状态(历史)
  2. 为您的班级提供该单独班级的私有实例
  3. 在该实例上订阅一些方法来处理example.MouseMove事件
  4. 在您的类中编写处理程序,以订阅您的单独类的该实例上的更高级别事件

这将绕过决定在哪里放置一个高度本地化的字段的问题。


例如:

class MouseTracker
{
    private Point _prevMousePosition = new Point(0, 0);
    //Maybe define some higher-level events here
    public event ... MouseMoveWithHistory;
    public void HandleMouseMove(object sender, MouseEventArgs e)
    {
        if (_prevMousePosition == Cursor.Position) return;
        //Do stuff
        //Trigger higher level events
    }
}

然后,在你的课堂上:

private MouseTracker tracker = new MouseTracker();
...
//in your constructor
example.MouseMove += tracker.HandleMouseMove;
tracker.MouseMoveWithHistory += tracker_SomeLocalHandler;
于 2013-06-05T17:21:42.437 回答
-1

与核心“实例变量放置?”无关 问题

“C# 中的鼠标移动事件一直在轮询。有时我可能只想在鼠标位置完全移动到另一个像素时才运行其中的代码。”

嗯?!......它不会因为“部分像素”而触发......如果这是这样的话。当你有一个基于整个像素的新位置时,它会触发。如果您离开表单然后在同一点重新输入,或者焦点切换然后返回并且光标没有移动,则可能具有相同的位置。在可能的情况下可能还有其他条件......但是您是否实际测试过新职位与先前职位匹配的频率?我不确定你在做什么,但它在我的系统上并不经常发生:

public partial class Form1 : Form
{

    public Form1()
    {
        InitializeComponent();
        this.MouseMove += new MouseEventHandler(example_MouseMove);
        listBox1.MouseMove += new MouseEventHandler(example_MouseMove);
        this.Shown += new EventHandler(Form1_Shown);
    }

    void Form1_Shown(object sender, EventArgs e)
    {
        _prevMousePosition = Cursor.Position;
    }

    private int counter = 0;
    private Point _prevMousePosition = new Point(0, 0);
    private void example_MouseMove(object sender, MouseEventArgs e)
    {
        if (_prevMousePosition == Cursor.Position)
        {
            counter++;
            listBox1.Items.Add(counter.ToString() + ": " + _prevMousePosition.ToString());
            listBox1.SelectedIndex = listBox1.Items.Count - 1;
        }
        else
        {
            _prevMousePosition = Cursor.Position;
            this.Text = _prevMousePosition.ToString();
        }
    }

}
于 2013-06-05T18:11:27.747 回答
-1

如果将其放入 MouseMove 事件中,一旦超出范围,您将失去该值。它应该放在班级级别。

于 2013-06-05T17:16:01.747 回答