BreadCrumb control made simple

breadCrumb

“Hard by a great forest dwelt a poor wood-cutter with his wife and his two children… Gretel took the bread under her apron, as Hansel had the pebbles in his pocket… Hansel, however, little by little, threw all the crumbs on the path…”

OK, ok, this was another story, however, the breadcrumb control is a great invention. It’s basically a horizontal way to navigate structures, like a folder structure, and generate a path through that structure. This is perfect for navigating through the Vault folder tree and select the path where to save our files with Data Standard.

breadCrumb

Now unfortunately, there is no Microsoft default control we could just use in our Data Standard dialogs. Fortunately, there are several vendors that offer great looking breadcrumb controls such as Telerik, Actipro, and others. Unfortunately, if you like to purchase one of these, read well the user license agreement, as Vault and Data Standard are “development platforms” themselves, so finally the Vault customer would have to purchase the license.

I took another approach. I thought why not having a list of cascading comboboxes. The list should be flexible and somewhat intelligent, in the sense that when I choose to change the path, the superfluous combos should be removed and replaced with the new selected path.

I know, this is not a 100% breadcrumb control and all of you skilled developers will laugh at me, but this is a cheap, simple, functional solution, so give me a break!

I took advantage of the StackPanel, which is a simple control that just stacks child controls either horizontal or vertical. In my case, I want the comboboxes stacked horizontally. The next step is to create and add dynamic comboboxes as child controls to the StackPanel, and fill them with the according list of Vault folders. As the user selects one folder from the first combo, a second combo will be added with the according child folders. As the user selects a folder from the second combo, a third will be added, and so on, until no more child folders exists. In case the user changes one of the previous folders, the child combos will be removed and the game starts over. Here is the code in the XAML.

...
<StackPanel Grid.Column="1" Grid.Row="4" Name="BreadCrumb" Orientation="Horizontal"/>
<!--ComboBox Grid.Column="1" Grid.Row="4" SelectedValue="{Binding Prop[Folder].Value}" SelectedIndex="0" Style="{StaticResource FolderStyle}" /-->
...

As you can see I just commented the combo box for the folder selection in the standard dialog and instead I’ve added the StackPanel mentioned above. As you can see the StackPanel is empty by default, but has a name. The rest is done in PowerShell.

In the InitializeWindow (Default.PS1), we take the starting folder and add them to the function AddCombo. The rest is done in a separate PS1 called breadcrumb.ps1.

$mappedRootPath = $Prop["_VaultVirtualPath"].Value + $Prop["_WorkspacePath"].Value
$mappedRootPath = $mappedRootPath -replace "\\", "/" -replace "//", "/"
$rootFolder = $vault.DocumentService.GetFolderByPath($mappedRootPath)
$root = New-Object PSObject -Property @{ Name = $rootFolder.Name; ID=$rootFolder.Id }
AddCombo -data $root

The function AddCombo gets the child Folders for the selected folder, adds a first combobox to our StackPanel, fills the combobox with the child folders and registers the SelectionChanged event. You will notice that the child folders are not just a list of text, but are little objects. The reason is that we want to store both, the name of the folder and the ID, so when we have to look for the children, we have the ID of the parent already at our hand.

function AddCombo($data)
{
 $children = GetChildFolders -folder $data
 if($children -eq $null) { return }
 $breadCrumb = $dsWindow.FindName("BreadCrumb")
 $cmb = New-Object System.Windows.Controls.ComboBox
 $cmb.Name = "cmbBreadCrumb_" + $breadCrumb.Children.Count.ToString()
 $cmb.DisplayMemberPath = "Name"
 $cmb.ItemsSource = @($children)
 $cmb.add_SelectionChanged({
 param($sender,$e)
 OnSelectionChanged -sender $sender
 })
 $breadCrumb.Children.Add($cmb)
}

The OnSelectionChanged is fired every time the user selects another value from the combo. In such case, we just take the selected folder and call the AddCombo with such folder. Before we do so, we remove all child combos, if they exist. That way, in case the user decided to go another path, the superfluous child combos get removed and the game can start over again.

function OnSelectionChanged($sender)
{
  $breadCrumb = $dsWindow.FindName("BreadCrumb")
  $position = [int]::Parse($sender.Name.Split('_')[1]);
  $children = $breadCrumb.Children.Count - 1
  while($children -gt $position )
  {
    $breadCrumb.Children.Remove($breadCrumb.Children[$children])
    $children--
  }
  $path = GetFullPathFromBreadCrumb -breadCrumb $breadCrumb
  $Prop["Folder"].Value = $path
  AddCombo -data $sender.SelectedItem
}

That’s it! there are two more little functions such as the GetFullPathFromBreadCrumb and GetChildFolders which contain few lines of code, but the real important functions are the two above. As you can see in the OnSelectionChanged the property Folder gets set whenever the user selects a new path.

If you like to try this code, you can download the complete sample from here https://github.com/coolOrange-Public/breadCrumb/archive/master.zip.

 

This entry was posted in Data Standard, PowerShell, Vault API. Bookmark the permalink.

5 Responses to BreadCrumb control made simple

  1. Max says:

    Thank you Coolorange,

    All the codes that you guys published really helps me going with Vault 2015 R2. I have now configured a complete dialog which has the following basic options.

    Based on the CAD document ( purchased, project or normal part) changes the properties and the save location with your folderpicker.
    I also add a way for normal parts to be saved on a location based on the automated number which will be generated.

  2. MKoe says:

    Marco, I suggest an easier approach to achieve that: pre-define several combo controls and add a style trigger:

    I don’t need any line of ps code to achieve that; however to fill each I am using cascading scripts.

    • Marco Mirandola says:

      Yeah, “many roads lead to rome” :-) i personally prefer to keep code in PowerShell scripts and have XAML only for design.

  3. JW says:

    To use it in Vault 2015 R1 comment out row 112 to 125 in inventor.xaml (disable NumScheme)

    <!–

    –>

Leave a Reply

Fill in your details below or click an icon to log in:

WordPress.com Logo

You are commenting using your WordPress.com account. Log Out / Change )

Twitter picture

You are commenting using your Twitter account. Log Out / Change )

Facebook photo

You are commenting using your Facebook account. Log Out / Change )

Google+ photo

You are commenting using your Google+ account. Log Out / Change )

Connecting to %s