See items information of a file

itemToFile

Have you ever wished to access item and BOM information right from your file without the need to actually go to it? Here is a Data Standard sample that solves this problem. It’s a little tab that shows item information with the according item BOM of the current selected CAD file.

The technique is somewhat easy. It’s basically one XAML and one PS1 file. While the XAML is straight forward, it’s a grid with properties and a DataGrid for the BOM:

<Grid>
  <Grid.ColumnDefinitions>
    <ColumnDefinition Width="*" />
    <ColumnDefinition Width="*" />
  </Grid.ColumnDefinitions>
  <Grid x:Name="ItemData" VerticalAlignment="Top" Margin="10">
    <Grid.ColumnDefinitions>
      <ColumnDefinition Width="80"/>
      <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <Grid.RowDefinitions>
      <RowDefinition/>
      <RowDefinition/>
      <RowDefinition/>
      <RowDefinition/>
      <RowDefinition/>
      <RowDefinition/>
    </Grid.RowDefinitions>
    <Label Content="Item"/>
    <TextBox Text="{Binding Item}" Grid.Column="1"/>
    <Label Content="Revision" Grid.Row="1"/>
    <TextBox Text="{Binding Revision}" Grid.Column="1" Grid.Row="1"/>
    <Label Content="Title" Grid.Row="2"/>
    <TextBox Text="{Binding Title}" Grid.Column="1" Grid.Row="2"/>
    <Label Content="Category" Grid.Row="3"/>
    <TextBox Text="{Binding Category}" Grid.Column="1" Grid.Row="3"/>
    <Label Content="State" Grid.Row="4"/>
    <TextBox Text="{Binding State}" Grid.Column="1" Grid.Row="4"/>
  </Grid>
  <Grid Grid.Column="1" Margin="10">
    <DataGrid Name="bomList" AutoGenerateColumns="True" IsReadOnly="True" ColumnWidth="Auto" HorizontalGridLinesBrush="WhiteSmoke" VerticalGridLinesBrush="WhiteSmoke"/>
  </Grid>
</Grid>

The PS1 file is a bit more work. We basically have to collect the item information first and then transform the BOM information into a small list that fits into the DataGrid:

Add-Type @"
public class itemData
{
  public string Item {get;set;}
  public string Revision {get;set;}
  public string Title {get;set;}
  public string Category {get;set;}
  public string State {get;set;}
}
"@

function OnTabContextChanged_Item
{
  $xamlFile = [System.IO.Path]::GetFileName($VaultContext.UserControl.XamlFile)
  if ($VaultContext.SelectedObject.TypeId.SelectionContext -eq "FileMaster" -and $xamlFile -eq "Item.xaml")
  {
    $fileMasterId = $vaultContext.SelectedObject.Id
    $file = $vault.DocumentService.GetLatestFileByMasterId($fileMasterId)
    $items = $vault.ItemService.GetItemsByFileId($file.Id)
    $item = $items[0]
    SetItemData -itemId $item.id
    SetItemBomData -itemId $item.id
  }
}

function SetItemData($itemId)
{
  $properyDefinitions = $vault.PropertyService.GetPropertyDefinitionsByEntityClassId("ITEM")
  $properties = $vault.PropertyService.GetPropertiesByEntityIds("ITEM",$itemId)
  $props = @{}
  foreach ($property in $properties) {
    $propDef = $properyDefinitions | Where-Object { $_.Id -eq $property.PropDefId }
    $props[$propDef.DispName] = $property.Val
  }
  $item = New-Object itemData
  $item.Item = $props["Number"]
  $item.Revision = $props["Revision"]
  $item.Title = $props["Title (Item,CO)"]
  $item.State = $props["State"]
  $item.Category = $props["Category Name"]
  $dsWindow.FindName("ItemData").DataContext = $item
}

function SetItemBomData($itemId)
{
  $BOM = $vault.ItemService.GetItemBOMByItemIdAndDate($itemId, [DateTime]::MinValue, [Autodesk.Connectivity.WebServices.BOMTyp]::Tip, [Autodesk.Connectivity.WebServices.BOMViewEditOptions]::Defaults)
  $assocs = $BOM.ItemAssocArray | Where-Object { $_.ParItemId -eq $itemId }
  $childIds = $assocs | ForEach-Object { $_.CldItemId }
  $properyDefinitions = $vault.PropertyService.GetPropertyDefinitionsByEntityClassId("ITEM")
  $properties = $vault.PropertyService.GetPropertiesByEntityIds("ITEM",$childIds)
  $data = @()
  foreach ($id in $childIds) {
    $props = @{}
    $ppys = $properties | Where-Object { $_.EntityId -eq $id }
    foreach ($property in $ppys) {
      $propDef = $properyDefinitions | Where-Object { $_.Id -eq $property.PropDefId }
      $props[$propDef.DispName] = $property.Val
    }
    $item = New-Object itemData
    $item.Item = $props["Number"]
    $item.Revision = $props["Revision"]
    $item.Title = $props["Title (Item,CO)"]
    $item.State = $props["State"]
    $item.Category = $props["Category Name"]
    $data += $item
  }
  $dsWindow.FindName("bomList").ItemsSource = $data
  $dsDiag.Trace("<< SetItemBomData")
}

As you can see, in the XAML file we bind the TextBoxes to some properties, like Item, Revision, Title, etc. Usually you would bind such TextBoxes to a Prop[Item].Value or Prop[Revision].Value. Well, by doing so we would just get the values from the selected file, but we want the values from the item linked to the selected file. Now, we can either set the values one by one to the according TextBoxes, from the PowerShell script that runs behind, but in this case, I’d like to show you a more elegant way. We basically create in PowerShell our little C# class that we then set as a DataContext to the Grid that contains the TextBoxes. This way, whichever control is inside the Grid, like our TextBoxes, will be bound to the new source of data. So the binding now works against our little C# class. So in the PowerShell we simply populate the properties of the class with values, inject the class as DataContext to the Grid, and let the binding do the rest. In order to have this working, the attributes of the class must be properties (get;set;).

The DataGrid receives the information in a similar way, but via the ItemsSource. The nice thing about the DataGrind is that with the option AutoGenerateColumns the columns will be automatically generated – less work for us.

The only thing that must be done is to modify the OnTabContextChanged in the default.ps1 and add our function OnTabContextChanged_Item so that our code gets executed whenever a new file gets selected.

If you like to get this sample running on your side, just download the sample from GitHub and follow the instruction.

Enjoy!!

 

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

2 Responses to See items information of a file

  1. Pingback: Select Vault items from within CAD | coolorange

  2. Jörg Weber says:

    Hallo Marco,
    ich habe den Reiter in mein Vault eingebaut und die Eigenschaften der Artikel so eingerichtet wie ich es gerne möchte. Wenn ich nun auf einem Bauteilartikel stehe wird auch fein die Stückliste angezeigt. Wenn ich dann aber auf ein Bauteilartikel gehe, dann bleibt die letzte Stückliste stehen. Solange bis ich ein anderen Bauteilartikel anwähle.
    Geht das, das wenn man auf ein Bauteilartikel steht, die Stückliste im rechten Bereich dann leer ist, und wenn ich auf ein Bauteilartikel stehe, die Stückliste angezeigt wird.
    viele Grüße
    Jörg

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