private void OnPropertyChanged(object sender, System.ComponentModel.PropertyChangedEventArgs e)
        {
            if (initSuccess)
            {
                if (e.PropertyName == "Index")
                {
                    initSuccess = false;
                    var categoryNode = sender as CategoryTreeNode;
                    if (categoryNode != null)
                    {
                        foreach (RuleTreeNode rule in categoryNode.Children)
                        {
                            rule.Index = categoryNode.Index;
                        }
                        base.IsDirty = true;
                        initSuccess  = true;
                    }
                    var ruleNode = sender as RuleTreeNode;
                    if (ruleNode != null)
                    {
                        CategoryTreeNode parent = ruleNode.Parent as CategoryTreeNode;
                        parent.CheckMode();
                        base.IsDirty = true;
                        initSuccess  = true;
                    }
                }


                if (e.PropertyName == "IsChecked")
                {
                    base.IsDirty = true;
                }
            }
        }
        void Callback(List <FxCopCategory> ruleList)
        {
            if (WorkbenchSingleton.InvokeRequired)
            {
                WorkbenchSingleton.SafeThreadAsyncCall((Action <List <FxCopCategory> >)Callback, ruleList);
            }
            else
            {
                ruleTreeView.Root = new SharpTreeNode();


                rules.Clear();
                if (ruleList == null || ruleList.Count == 0)
                {
                    ruleTreeView.Root.Children.Add(new MessageNode(StringParser.Parse("${res:ICSharpCode.CodeAnalysis.ProjectOptions.CannotFindFxCop}")));
                    ruleTreeView.Root.Children.Add(new MessageNode(StringParser.Parse("${res:ICSharpCode.CodeAnalysis.ProjectOptions.SpecifyFxCopPath}")));
                }
                else
                {
                    foreach (FxCopCategory cat in ruleList)
                    {
                        CategoryTreeNode catNode = new CategoryTreeNode(cat);
                        catNode.PropertyChanged += OnPropertyChanged;
                        ruleTreeView.Root.Children.Add(catNode);
                        foreach (RuleTreeNode ruleNode in catNode.Children)
                        {
                            ruleNode.PropertyChanged  += OnPropertyChanged;
                            rules[ruleNode.Identifier] = ruleNode;
                        }
                    }
                    ReadRuleString();
                    initSuccess = true;
                }
            }
        }
		void Callback(List<FxCopCategory> ruleList)
		{
			if (WorkbenchSingleton.InvokeRequired) {
				WorkbenchSingleton.SafeThreadAsyncCall((Action<List<FxCopCategory>>)Callback, ruleList);
			} else {
				ruleTreeView.Nodes.Clear();
				rules.Clear();
				if (ruleList == null || ruleList.Count == 0) {
					ruleTreeView.Nodes.Add(new TreeNode(StringParser.Parse("${res:ICSharpCode.CodeAnalysis.ProjectOptions.CannotFindFxCop}")));
					ruleTreeView.Nodes.Add(new TreeNode(StringParser.Parse("${res:ICSharpCode.CodeAnalysis.ProjectOptions.SpecifyFxCopPath}")));
				} else {
					foreach (FxCopCategory cat in ruleList) {
						CategoryTreeNode catNode = new CategoryTreeNode(cat);
						ruleTreeView.Nodes.Add(catNode);
						foreach (RuleTreeNode ruleNode in catNode.Nodes) {
							rules[ruleNode.Identifier] = ruleNode;
						}
					}
					initSuccess = true;
					ReadRuleString();
				}
			}
		}
		void Callback(List<FxCopCategory> ruleList)
		{
			if (SD.MainThread.InvokeRequired) {
				SD.MainThread.InvokeAsync(() => Callback(ruleList));
			} else {
				ruleTreeView.Root = new SharpTreeNode();
				
				rules.Clear();
				if (ruleList == null || ruleList.Count == 0) {
					ruleTreeView.Root.Children.Add(new MessageNode(StringParser.Parse("${res:ICSharpCode.CodeAnalysis.ProjectOptions.CannotFindFxCop}")));
					ruleTreeView.Root.Children.Add(new MessageNode(StringParser.Parse("${res:ICSharpCode.CodeAnalysis.ProjectOptions.SpecifyFxCopPath}")));
				} else {
					foreach (FxCopCategory cat in ruleList) {
						CategoryTreeNode catNode = new CategoryTreeNode(cat);
						catNode.PropertyChanged += OnPropertyChanged;
						ruleTreeView.Root.Children.Add(catNode);
						foreach (RuleTreeNode ruleNode in catNode.Children) {
							ruleNode.PropertyChanged += OnPropertyChanged;
							rules[ruleNode.Identifier] = ruleNode;
						}
					}
					ReadRuleString();
					initSuccess = true;
				}
			}
		}