The Explorer actions
The smaller action buttons are available when the Rules Explorer window is open.
The Ribbon class contains a method to test if this Explorer Window is open for the active document:
public static bool IsExplorerWindowOpen(Visio.Document document)
{
//Check if the explorer window is open
if (document != null)
{
foreach (Visio.Window win in document.Application.Windows)
{
if (win.Document == document)
{
foreach (Visio.Window subWin in win.Windows)
{
if (subWin.Caption == Globals.AnchorBarTitle)
{
return subWin.Visible;
}
}
}
}
}
return false;
}
The particular actions that
the buttons perform depend upon the type of item selected in the tree
view. Therefore, I added a couple of methods to the Ribbon class that test if a VERuleSet or VERule is selected in the tree view.
public static bool IsRuleSetSelected(Visio.Document document)
{
if (document != null)
{
//Get the VEDocument
ViewModel.VEDocument ved =
Globals.ThisAddIn.VEApp.VEDocuments.Single( doc => doc.ID == document.ID);
//Test if SelectedRuleSet is null
return ved.SelectedVERuleSet != null;
}
return false;
}
public static bool IsRuleSelected(Visio.Document document)
{
if (document != null)
{
//Get the VEDocument
ViewModel.VEDocument ved = Globals.ThisAddIn.VEApp.VEDocuments.Single( doc => doc.ID == document.ID);
//Test if SelectedRule is null
return ved.SelectedVERule != null;
}
return false;
}
Of course, something needs to set the SelectedVERuleSet and SelectedVERule properties of the active VEDocument instance. This is done in the TreeViewMain_SelectedItemChanged() event in the code in the UserControlExplorer.xaml file. This event is also used to set the DataContext of the expanders for the RuleSet and Rule Properties panels.
The Add button
The Add
button action will add a rule set if a document is selected in the tree
view, but it will add a rule if a rule set is selected in the tree
view. Then, the new item itself is automatically selected in the tree
view.
The OnAction(Office.IRibbonControl control) callback defines the case for the buttonRuleAdd button. It tests if a VEDocument or VERuleSet is selected, and then calls the relevant method in the VEDocument object.
case "buttonRuleAdd":
{
//Only enable if a ruleset or rule is selected
bool isWinOpen = Ribbon.IsExplorerWindowOpen( Globals.ThisAddIn.Application.ActiveDocument);
if (isWinOpen)
{
if (Ribbon.IsRuleSetSelected( Globals.ThisAddIn.Application.ActiveDocument))
{
Globals.ThisAddIn.VEApp.SelectedVEDocument.AddRule();
}
else if (!Ribbon.IsRuleSelected( Globals.ThisAddIn.Application.ActiveDocument))
{
Globals.ThisAddIn.VEApp.SelectedVEDocument.AddRuleSet();
}
else
{
System.Windows.MessageBox.Show(
this.GetSupertip(control),
this.GetLabel(control),
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Information);
}
}
else
{
System.Windows.MessageBox.Show(this.GetSupertip(control),
this.GetLabel(control),
System.Windows.MessageBoxButton.OK,
System.Windows.MessageBoxImage.Information) ;
}
break;
}
For example, the AddRule() method ensures that a unique new name is proposed, and then passed through to the AddRule() method of the VERuleSet object.
public void AddRule()
{
try
{
if (this.SelectedVERuleSet != null)
{
//Add a rule
string newName = this.SelectedVERuleSet.VERules.SuggestRuleName();
VERule ver = this.selectedVERuleSet.VERules.AddRule(newName);
this.selectedVERuleSet.SelectedVERule = ver;
this.selectedVERule = this.selectedVERuleSet.SelectedVERule;
}
}
catch (Exception)
{
throw;
}
}
public VERule AddRule(string NameU)
{
Visio.ValidationRule rul = rules.Add(NameU);
this.Add(new VERule(rul, veRuleSet));
OnPropertyChanged(new PropertyChangedEventArgs("GetCount"));
this.VERuleSet.RaisePropertyChanged("DisplayName");
return this.Single(ver => ver.NameU == NameU);
}
Notice that this method creates a new Visio.ValidationRule first, then adds this to the VERules ObservableCollection. It then calls the OnPropertyChanged() method to ensure that the UI display of the VERules is updated.
The AddRuleSet() method is similar to the AddRule() method.
The Add Issue button
The Add Issue button action will simply add an issue to a rule.
The AddRuleIssue() method in the VEDocument class establishes the TargetType of the rule, then adds the issue to the relevant item or items.
public void AddRuleIssue()
{
try
{
if (this.SelectedVERule != null)
{
//Add an issue for the rule
if (this.selectedVERule.TargetType == Visio.VisRuleTargets.visRuleTargetDocument)
{
Visio.ValidationIssue iss= this.selectedVERule.AddIssue();
this.VEIssues.AddIssue(iss);
}
else if (this.selectedVERule.TargetType == Visio.VisRuleTargets.visRuleTargetDocument)
{
Visio.ValidationIssue iss = this.selectedVERule.AddIssue( document.Application.ActivePage);
this.VEIssues.AddIssue(iss);
}
else
{
foreach (Visio.Shape shp in document.Application.ActiveWindow.Selection)
{
Visio.ValidationIssue iss =
this.selectedVERule.AddIssue( document.Application.ActivePage,shp);
this.VEIssues.AddIssue(iss);
}
}
}
}
catch (Exception)
{
throw;
}
}
The Paste button
The Paste button action will paste a previously copied rule set or rule to the selected document or rule set respectively.
The VEApplication.PasteRule() method establishes that a VERuleSet item is selected, and that there is a temporary VERule object copied. It then calls the VERules.PasteRule() method.
public void PasteRule()
{
if (this.SelectedVERuleSet != null && tempRule != null)
{
VERule newVer = this.SelectedVERuleSet.VERules.PasteRule(tempRule);
this.SelectedVEDocument.SelectedVERule = newVer;
}
}
The VERules.PasteRule() method checks if a new unique name is required before creating a new rule, and cloning the properties:
public VERule PasteRule(VERule sourceRule)
{
VERule newVer = null;
if (this.Count(ver => ver.NameU == sourceRule.NameU) == 0)
{
//Use same name
newVer = this.AddRule(sourceRule.NameU);
}
else
{
//Get a new name
string newName = this.SuggestRuleName();
newVer = this.AddRule(newName);
}
//Set all of the Visio Validation properties
newVer.Ignored = sourceRule.Ignored;
newVer.Category = sourceRule.Category;
newVer.Description = sourceRule.Description;
newVer.FilterExpression = sourceRule.FilterExpression;
newVer.TestExpression = sourceRule.TestExpression;
newVer.TargetType = sourceRule.TargetType;
OnPropertyChanged(new PropertyChangedEventArgs("GetCount"));
this.VERuleSet.RaisePropertyChanged("DisplayName");
return newVer;
}
The Copy button
The Copy action will take a copy of the selected rule set or rule, so that it is available for the Paste action.
The VEApplication.CopyRule() method simply copies the SelectedVERule object to a temporary object, and then ensures that the HasTempRule property is notified.
public void CopyRule()
{
tempRule = this.SelectedVERule;
OnPropertyChanged("HasTempRule");
}
There is a similar VEApplication.CopyRuleSet() method, which is called if the user has a VERuleSet object selected in the Validation Explorer tree view, rather than a VERule object.
The Delete button
The Delete action enables the user to delete the selected rule set or rule.
The VERules.DeleteRule() method ensures that the Visio.ValidationRules collection and the VERules ObservableCollection are kept synchronized.
public void DeleteRule(VERule ver)
{
Visio.ValidationRule rul = this.rules[ver.NameU];
this.Remove(ver);
rul.Delete();
OnPropertyChanged(new PropertyChangedEventArgs("GetCount"));
this.VERuleSet.RaisePropertyChanged("DisplayName");
}
There is a similar VERuleSets.DeleteRuleSet() method, which is called if the user has a VERuleSet object selected in the Validation Explorer tree view, rather than a VERule object.