每次我打开Visual Studio时,FileSystemWatcher的EnableRaisingEvent属性都会发生变化。

5
我在Visual Studio 2010中使用C#和框架4.0。在我的项目中,有两个不同的表单中,都有两个FileSystemWatcher,其EnableRaisingEvent属性设置为false。如果我关闭Visual Studio,重新打开后,这两个FileSystemWatcher的EnableRaisingEvent属性都会被设置为true。在我的设计文件中,这两个表单中都有以下代码:
private void InitializeComponent()
{
     this.components = new System.ComponentModel.Container();
     System.ComponentModel.ComponentResourceManager resources = new System.ComponentModel.ComponentResourceManager(typeof(Form1));
     this.fileSystemWatcher1 = new System.IO.FileSystemWatcher();
     ((System.ComponentModel.ISupportInitialize)(this.fileSystemWatcher1)).BeginInit();   
     this.SuspendLayout();

     this.fileSystemWatcher1.Filter = "my_filter";
     this.fileSystemWatcher1.NotifyFilter = System.IO.NotifyFilters.LastWrite;
     this.fileSystemWatcher1.SynchronizingObject = this;
     this.fileSystemWatcher1.Changed += new System.IO.FileSystemEventHandler(this.fileSystemWatcher1_Changed);
}

属性EnableRaisingEvent未设置,但默认值为false

有任何想法为什么会出现这种奇怪的行为?

编辑

我按照Virtlink的建议添加了以下代码行:

this.fileSystemWatcher1.EnableRaisingEvents = false;

看起来解决了我的问题,但几天后(并且打开、关闭和重建项目,但没有修改fileSystemWatcher1)我发现:

  • 在设计器中,在fileSystemWatcher1的属性中,EnableRaisingEvents被设置回true

  • 在代码中,先前添加的行消失了

我尝试转移到Visual Studio 2012(仍然是框架4.0),解决方法可以再工作几天。然后我遇到了与VS10相同的情况。

还有其他想法吗?


你能确认一下,在你的Form.cs文件的构造函数中,是否添加了Virtlink的建议“this.fileSystemWatcher1.EnableRaisingEvents = false;”吗? - jacob aloysious
@jacobaloysious 我试了一下,似乎解决了问题!谢谢你。 - 888
3个回答

2

这个问题也出现在 Visual Studio 2012 中,你不需要关闭 Visual Studio。重新打开表单设计器就足以将属性设置为True,在设计器中和运行时都是如此。

这似乎是FileSystemWatcher的一个bug。

一种解决方法是在InitializeComponent中显式添加这一行:

this.fileSystemWatcher1.EnableRaisingEvents = false;

如果设计师不愿意与您合作,您就必须反其道而行之。任何放在InitializeComponent中的内容都可能被设计师覆盖或删除,因为InitializeComponent是设计师的领地。解决这个问题的一种方法是在窗体构造函数中,在调用InitializeComponent后立即添加该行。

InitializeComponent();
this.fileSystemWatcher1.EnableRaisingEvents = false;

这意味着设计师不会向您显示EnableRaisingEvents的正确值,但由于它本身并不起作用,这可能不是一个大问题。将该行代码放在构造函数中可确保它不会在未来的任何时候被设计师删除。

1
我赞同Virtlink的建议,在代码中添加需要的行,例如:
  public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
            this.fileSystemWatcher1.EnableRaisingEvents = false;
        }
    }    

以下是我找到的更多理由,支持你不应该(绝不)编辑你的 designer.cs:

您可以从Herenvardo的评论这里中获得更多信息。以下是它的简要内容:

无论出于何种原因,编辑 .Designer.cs(或 Visual Basic 中的 .Designer.vb)文件都是不可取的,几乎从不需要。有两个主要原因解释为什么编辑这些文件是如此不可取:

  1. 集成开发环境使用非常严格的编码规范来编写这些文件,并期望它们遵循这些规范(比如空格和缩进不会引起问题,但任何改变文件结构或代码解析树的东西都可能产生严重的副作用)。
  2. 在许多情况下,集成开发环境可能会在没有通知你的情况下覆盖你的更改。一般来说,对于窗体或用户控件的.designer文件,只要你从设计器中进行了更改,该文件就会被覆盖。对于设置文件(我对这些没有太多实践经验),我猜测当你从IDE本身的项目属性设置页面编辑设置时,它们将被重新编写。最简单的方法是假定IDE随时可能更改任何.designer文件,出于任何原因。尽管IDE何时编写每个文件已经定义得很好,但很难知道和记住每个文件何时以及为什么可以重新制作,所以最好保险起见。

虽然不建议这样做,但是如果保留文件结构,您可以编辑设计师文件。例如,通常会删除事件处理程序,有时也可能添加一个值“就像设计师设置的一样”。这两种情况通常也可以通过设计师本身实现,因此没有必要进行编辑。 - Daniel A.A. Pelsmaeker

1
现在我并不指望这个答案会被采纳,但还是要说一下。我写了一个小的预处理程序,可以读取和修改Visual Studio项目中的C#源文件,并进行一些有趣的操作,例如提供一些本地化服务,在我的日志语句中插入唯一的日志标记等。这个预处理程序由所有.csproj文件中的BeforeBuild目标调用,因此它将作为每次编译的一部分运行。
我目前没有修改.Designer.cs文件,但我正在修改.resx文件,并且它们具有与Visual Studio设计器相同的不幸特性,因此每当我更改表单时,我的修改就会被丢弃,但是我的预处理程序会重新修改.resx文件。每当Visual Studio设计器丢弃它时,重新插入设置EnableRaisingEvents为false的语句都将遵循相同的过程。这可能有点大材小用,但它会起作用。
编辑:

对于任何考虑实施此技术来解决类似问题的人,本帖子包含一些有关如何使Visual Studio与预处理器共存的技巧:如何在BeforeBuild处理后让Visual Studio重新读取源文件?


网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接