应用程序名称:RvtSamples

Revit平台:所有平台

Revit版本:2011.0

首次发布版本:2009.0

编程语言:C#

熟练程度:初学者

类别:基础知识

类型:外部应用程序

主题:将示例菜单项添加到Revit中。

摘要:

此示例将所有示例(除外部应用程序之外)集成到一个名为RvtSamples”的面板中,该面板位于“添加-插件”菜单下。

相关类:

Autodesk.Revit.ApplicationServices.ControlledApplication

Autodesk.Revit.UI.RibbonPanel

Autodesk.Revit.UI.PulldownButton

Autodesk.Revit.UI.PulldownButtonData

Autodesk.Revit.UI.PushButton

Autodesk.Revit.UI.PushButtonData

项目文件:

Application.cs

它包含实现接口IExternalApplication的类Application

描述:

此示例提供以下功能。

- 从名为“RvtSamples.txt”的提供的文本文件中提取示例信息并将它们解析成菜单项。该文件可进行自定义,但必须遵循以下固定格式。

每个菜单项由七行组成。

  1. 第一行表示示例所属的下拉菜单的名称。该下拉菜单将在功能区上可用,并将根据需要添加与其关联的命令。默认情况下,Revit SDK中包含12个下拉菜单以组织示例。这12个示例将具有适当的图标,并将自动显示在功能区上。如果选择输入不属于这12个下拉菜单之一的下拉菜单名称,则您的下拉菜单将在面板的最右侧添加,而没有图标。

2. 第二行表示示例的显示名称。

3. 第三行表示菜单项的描述。

4. 第四行表示“RibbonItem.LargeImage”属性。这应该是一个32x32像素的图像文件的路径,用于显示此命令的按钮。如果没有要显示的图像,请将此行留空。

5. 第五行表示“RibbonItem.Image”属性。这应该是一个16x16像素的图像文件的路径,如果将命令提升到快速访问工具栏,则将显示该图像。如果没有要显示的图像,请将此行留空。

6. 第六行表示菜单项的程序集位置路径。

[注意] 在提供的文本文件中,每个项目都提供了在驱动器Z中的默认路径。要成功运行示例,请将默认路径修改为您本地驱动器上的示例实际路径。假设您的示例本地路径为C\ Revit \ SDK2009,则可以将文本文件中所有“ Z:”替换为“ C\ Revit”,或者创建虚拟驱动器Z(通过运行dos命令“ SUBST ZC\ Revit \ SDK2009”)。

4. 最后一行表示菜单项的类名。

- RvtSamples.txt可以进行自定义,包括其他文件,其中包含示例列表。这些文件必须遵循以上固定格式。要在RvtSamples.txt”中包含的每个文件都应添加到“ RvtSamples.txt”中,并且该行应该以“ #include”(不区分大小写)开头。文件路径可以用“”,<>或不带引号的方式引用

源代码:

完整的源代码请加入QQ群649037449,在群文件中下载RevitSDK.exe,解压后在文件夹中搜索本文中应用程序名称即可获得完整源码

Application.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
//

using System;
using System.Collections;
using System.Diagnostics;
using System.IO;
using System.Reflection;
using System.Windows.Forms;
using System.Collections.Generic;
using System.Windows.Media.Imaging;

using Autodesk.Revit;
using Autodesk.Revit.UI;
using Autodesk.Revit.ApplicationServices;

namespace RvtSamples
{
/// <summary>
/// Main external application class.
/// A generic menu generator application.
/// Read a text file and add entries to the Revit menu.
/// Any number and location of entries is supported.
/// </summary>
public class Application : IExternalApplication
{
/// <summary>
/// Default pulldown menus for samples
/// </summary>
public enum DefaultPulldownMenus
{
/// <summary>
/// Menu for Basics category
/// </summary>
Basics,
/// <summary>
/// Menu for Geometry category
/// </summary>
Geometry,
/// <summary>
/// Menu for Parameters category
/// </summary>
Parameters,
/// <summary>
/// Menu for Elements category
/// </summary>
Elements,
/// <summary>
/// Menu for Families category
/// </summary>
Families,
/// <summary>
/// Menu for Materials category
/// </summary>
Materials,
/// <summary>
/// Menu for Annotation category
/// </summary>
Annotation,
/// <summary>
/// Menu for Views category
/// </summary>
Views,
/// <summary>
/// Menu for Rooms/Spaces category
/// </summary>
RoomsAndSpaces,
/// <summary>
/// Menu for Data Exchange category
/// </summary>
DataExchange,
/// <summary>
/// Menu for MEP category
/// </summary>
MEP,
/// <summary>
/// Menu for Structure category
/// </summary>
Structure,
/// <summary>
/// Menu for Analysis category
/// </summary>
Analysis,
/// <summary>
/// Menu for Massing category
/// </summary>
Massing,
/// <summary>
/// Menu for Selection category
/// </summary>
Selection
}

#region Member Data
/// <summary>
/// Separator of category for samples have more than one category
/// </summary>
static char[] s_charSeparatorOfCategory = new char[] { ',' };
/// <summary>
/// chars which will be trimmed in the file to include extra sample list files
/// </summary>
static char[] s_trimChars = new char[] { ' ', '"', '\'', '<', '>' };
/// <summary>
/// The start symbol of lines to include extra sample list files
/// </summary>
static string s_includeSymbol = "#include";
/// <summary>
/// Assembly directory
/// </summary>
static string s_assemblyDirectory = Path.GetDirectoryName(System.Reflection.Assembly.GetExecutingAssembly().Location);
/// <summary>
/// Name of file which contains information required for menu items
/// </summary>
public const string m_fileNameStem = "RvtSamples.txt";
/// <summary>
/// The controlled application of Revit
/// </summary>
private UIControlledApplication m_application;
/// <summary>
/// List contains all pulldown button items contain sample items
/// </summary>
private SortedList<string, PulldownButton> m_pulldownButtons = new SortedList<string, PulldownButton>();
/// <summary>
/// List contains information of samples not belong to default pulldown menus
/// </summary>
private SortedList<string, List<SampleItem>> m_customizedMenus = new SortedList<string, List<SampleItem>>();
/// <summary>
/// List contains information of samples belong to default pulldown menus
/// </summary>
private SortedList<string, List<SampleItem>> m_defaultMenus = new SortedList<string, List<SampleItem>>();
/// <summary>
/// Panel for RvtSamples
/// </summary>
RibbonPanel m_panelRvtSamples;
#endregion // Member Data

#region IExternalApplication Members
/// <summary>
/// Implement this method to implement the external application which should be called when
/// Revit starts before a file or default template is actually loaded.
/// </summary>
/// <param name="application">An object that is passed to the external application
/// which contains the controlled application.</param>
/// <returns>Return the status of the external application.
/// A result of Succeeded means that the external application successfully started.
/// Cancelled can be used to signify that the user cancelled the external operation at
/// some point.
/// If false is returned then Revit should inform the user that the external application
/// failed to load and the release the internal reference.</returns>
public Autodesk.Revit.UI.Result OnStartup(UIControlledApplication application)
{
m_application = application;
Autodesk.Revit.UI.Result rc = Autodesk.Revit.UI.Result.Failed;
string[] lines = null;
int n = 0;
int k = 0;

try
{
// Check whether the file contains samples' list exists
// If not, return failure
string filename = m_fileNameStem;
if (!GetFilepath(ref filename))
{
ErrorMsg(m_fileNameStem + " not found.");
return rc;
}

// Read all lines from the file
lines = ReadAllLinesWithInclude(filename);
// Remove comments
lines = RemoveComments(lines);

// Add default pulldown menus of samples to Revit
m_panelRvtSamples = application.CreateRibbonPanel("RvtSamples");
int i = 0;
List<PulldownButtonData> pdData = new List<PulldownButtonData>(3);
foreach (string category in Enum.GetNames(typeof(DefaultPulldownMenus)))
{
if ((i + 1) % 3 == 1)
{
pdData.Clear();
}

//
// Prepare PulldownButtonData for add stacked buttons operation
//
string displayName = GetDisplayNameByEnumName(category);

List<SampleItem> sampleItems = new List<SampleItem>();
m_defaultMenus.Add(category, sampleItems);

PulldownButtonData data = new PulldownButtonData(displayName, displayName);
pdData.Add(data);

//
// Add stacked buttons to RvtSamples panel and set their display names and images
//
if ((i + 1) % 3 == 0)
{
IList<RibbonItem> addedButtons = m_panelRvtSamples.AddStackedItems(pdData[0], pdData[1], pdData[2]);
foreach (RibbonItem item in addedButtons)
{
String name = item.ItemText;
string enumName = GetEnumNameByDisplayName(name);
PulldownButton button = item as PulldownButton;
button.Image = new BitmapImage(
new Uri(Path.Combine(s_assemblyDirectory, "Icons\\" + enumName + ".ico"), UriKind.Absolute));
button.ToolTip = Properties.Resource.ResourceManager.GetString(enumName);
m_pulldownButtons.Add(name, button);
}
}

i++;
}

//
// Add sample items to the pulldown buttons
//
n = lines.GetLength(0);
k = 0;
while (k < n)
{
AddSample(lines, n, ref k);
}

AddSamplesToDefaultPulldownMenus();
AddCustomizedPulldownMenus();

rc = Autodesk.Revit.UI.Result.Succeeded;
}
catch (Exception e)
{
string s = string.Format("{0}: n = {1}, k = {2}, lines[k] = {3}",
e.Message, n, k, (k < n ? lines[k] : "eof"));

ErrorMsg(s);
}
return rc;
}

/// <summary>
/// Get a button's enum name by its display name
/// </summary>
/// <param name="name">display name</param>
/// <returns>enum name</returns>
private string GetEnumNameByDisplayName(string name)
{
string enumName = null;
if (name.Equals("Rooms/Spaces"))
{
enumName = DefaultPulldownMenus.RoomsAndSpaces.ToString();
}
else if (name.Equals("Data Exchange"))
{
enumName = DefaultPulldownMenus.DataExchange.ToString();
}
else
{
enumName = name;
}

return enumName;
}

/// <summary>
/// Get a button's display name by its enum name
/// </summary>
/// <param name="enumName">The button's enum name</param>
/// <returns>The button's display name</returns>
private string GetDisplayNameByEnumName(string enumName)
{
string displayName = null;
if (enumName.Equals(DefaultPulldownMenus.RoomsAndSpaces.ToString()))
{
displayName = "Rooms/Spaces";
}
else if (enumName.Equals(DefaultPulldownMenus.DataExchange.ToString()))
{
displayName = "Data Exchange";
}
else
{
displayName = enumName;
}

return displayName;
}

/// <summary>
/// Implement this method to implement the external application which should be called when
/// Revit is about to exit,Any documents must have been closed before this method is called.
/// </summary>
/// <param name="application">An object that is passed to the external application
/// which contains the controlled application.</param>
/// <returns>Return the status of the external application.
/// A result of Succeeded means that the external application successfully shutdown.
/// Cancelled can be used to signify that the user cancelled the external operation at
/// some point.
/// If false is returned then the Revit user should be warned of the failure of the external
/// application to shut down correctly.</returns>
public Autodesk.Revit.UI.Result OnShutdown(UIControlledApplication application)
{
return Autodesk.Revit.UI.Result.Succeeded;
}
#endregion // IExternalApplication Members

/// <summary>
/// Display error message
/// </summary>
/// <param name="msg">Message to display</param>
public void ErrorMsg(string msg)
{
Debug.WriteLine("RvtSamples: " + msg);
TaskDialog.Show("RvtSamples", msg, TaskDialogCommonButtons.Ok);
}

#region Parser
/// <summary>
/// Read file contents, including contents of files included in the current file
/// </summary>
/// <param name="filename">Current file to be read</param>
/// <returns>All lines of file contents</returns>
private string[] ReadAllLinesWithInclude(string filename)
{
if (!File.Exists(filename))
{
ErrorMsg(filename + " not found.");
return new string[] { };
}
string[] lines = File.ReadAllLines(filename);

int n = lines.GetLength(0);
ArrayList all_lines = new ArrayList(n);
foreach (string line in lines)
{
string s = line.TrimStart();
if (s.ToLower().StartsWith(s_includeSymbol))
{
string filename2 = s.Substring(s_includeSymbol.Length);
filename2 = filename2.Trim(s_trimChars);
all_lines.AddRange(ReadAllLinesWithInclude(filename2));
}
else
{
all_lines.Add(line);
}
}
return all_lines.ToArray(typeof(string)) as string[];
}

/// <summary>
/// Get the input file path.
/// Search and return the full path for the given file
/// in the current exe directory or one or two directory levels higher.
/// </summary>
/// <param name="filename">Input filename stem, output full file path</param>
/// <returns>True if found, false otherwise.</returns>
bool GetFilepath(ref string filename)
{
string path = Path.Combine(s_assemblyDirectory, filename);
bool rc = File.Exists(path);

// Get full path of the file
if (rc)
{
filename = Path.GetFullPath(path);
}
return rc;
}

/// <summary>
/// Remove all comments and empty lines from a given array of lines.
/// Comments are delimited by '#' to the end of the line.
/// </summary>
string[] RemoveComments(string[] lines)
{
int n = lines.GetLength(0);
string[] a = new string[n];
int i = 0;
foreach (string line in lines)
{
string s = line;
int j = s.IndexOf('#');
if (0 <= j)
{
s = s.Substring(0, j);
}
s = s.Trim();
if (0 < s.Length)
{
a[i++] = s;
}
}
string[] b = new string[i];
n = i;
for (i = 0; i < n; ++i)
{
b[i] = a[i];
}
return b;
}
#endregion // Parser

#region Menu Helpers
/// <summary>
/// Add a new command to the corresponding pulldown button.
/// </summary>
/// <param name="lines">Array of lines defining sample's category, display name, description, large image, image, assembly and classname</param>
/// <param name="n">Total number of lines in array</param>
/// <param name="i">Current index in array</param>
void AddSample(string[] lines, int n, ref int i)
{
if (n < i + 6)
{
throw new Exception(string.Format("Incomplete record at line {0} of {1}", i, m_fileNameStem));
}

string categories = lines[i++].Trim();
string displayName = lines[i++].Trim();
string description = lines[i++].Trim();
string largeImage = lines[i++].Remove(0, 11).Trim();
string image = lines[i++].Remove(0, 6).Trim();
string assembly = lines[i++].Trim();
string className = lines[i++].Trim();

if (!File.Exists(assembly)) // jeremy
{
ErrorMsg(string.Format("Assembly '{0}' specified in line {1} of {2} not found",
assembly, i, m_fileNameStem));
}

bool testClassName = false; // jeremy
if (testClassName)
{
Debug.Print("RvtSamples: testing command {0} in assembly '{1}'.", className, assembly);

try
{
// first load the revit api assembly, otherwise we cannot query the external app for its types:

//Assembly revit = Assembly.LoadFrom( "C:/Program Files/Revit Architecture 2009/Program/RevitAPI.dll" );
//string root = "C:/Program Files/Autodesk Revit Architecture 2010/Program/";
//Assembly adWindows = Assembly.LoadFrom( root + "AdWindows.dll" );
//Assembly uiFramework = Assembly.LoadFrom( root + "UIFramework.dll" );
//Assembly revit = Assembly.LoadFrom( root + "RevitAPI.dll" );

// load the assembly into the current application domain:

Assembly a = Assembly.LoadFrom(assembly);

if (null == a)
{
ErrorMsg(string.Format("Unable to load assembly '{0}' specified in line {1} of {2}",
assembly, i, m_fileNameStem));
}
else
{
// get the type to use:
Type t = a.GetType(className);
if (null == t)
{
ErrorMsg(string.Format("External command class {0} in assembly '{1}' specified in line {2} of {3} not found",
className, assembly, i, m_fileNameStem));
}
else
{
// get the method to call:
MethodInfo m = t.GetMethod("Execute");
if (null == m)
{
ErrorMsg(string.Format("External command class {0} in assembly '{1}' specified in line {2} of {3} does not define an Execute method",
className, assembly, i, m_fileNameStem));
}
}
}
}
catch (Exception ex)
{
ErrorMsg(string.Format("Exception '{0}' \ntesting assembly '{1}' \nspecified in line {2} of {3}",
ex.Message, assembly, i, m_fileNameStem));
}
}

//
// If sample belongs to default category, add the sample item to the sample list of the default category
// If not, store the information for adding to RvtSamples panel later
//
string[] entries = categories.Split(s_charSeparatorOfCategory, StringSplitOptions.RemoveEmptyEntries);
foreach (string value in entries)
{
string category = value.Trim();
SampleItem item = new SampleItem(category, displayName, description, largeImage, image, assembly, className);
if (m_pulldownButtons.ContainsKey(category))
{
m_defaultMenus.Values[m_defaultMenus.IndexOfKey(GetEnumNameByDisplayName(category))].Add(item);
}
else if (m_customizedMenus.ContainsKey(category))
{
List<SampleItem> sampleItems = m_customizedMenus.Values[m_customizedMenus.IndexOfKey(category)];
sampleItems.Add(item);
}
else
{
List<SampleItem> sampleItems = new List<SampleItem>();
sampleItems.Add(item);
m_customizedMenus.Add(category, sampleItems);
}
}
}

/// <summary>
/// Add sample item to pulldown menu
/// </summary>
/// <param name="pullDownButton">Pulldown menu</param>
/// <param name="item">Sample item to be added</param>
private void AddSampleToPulldownMenu(PulldownButton pullDownButton, SampleItem item)
{
PushButtonData pushButtonData = new PushButtonData(item.DisplayName, item.DisplayName, item.Assembly, item.ClassName);
PushButton pushButton = pullDownButton.AddPushButton(pushButtonData);
if (!string.IsNullOrEmpty(item.LargeImage))
{
BitmapImage largeImageSource = new BitmapImage(new Uri(item.LargeImage, UriKind.Absolute));
pushButton.LargeImage = largeImageSource;
}
if (!string.IsNullOrEmpty(item.Image))
{
BitmapImage imageSource = new BitmapImage(new Uri(item.Image, UriKind.Absolute));
pushButton.Image = imageSource;
}

pushButton.ToolTip = item.Description;
}

/// <summary>
/// Comparer to sort sample items by their display name
/// </summary>
/// <param name="s1">sample item 1</param>
/// <param name="s2">sample item 2</param>
/// <returns>compare result</returns>
private static int SortByDisplayName(SampleItem item1, SampleItem item2)
{
return string.Compare(item1.DisplayName, item2.DisplayName);
}

/// <summary>
/// Sort samples in one category by the sample items' display name
/// </summary>
/// <param name="menus">samples to be sorted</param>
private void SortSampleItemsInOneCategory(SortedList<string, List<SampleItem>> menus)
{
int iCount = menus.Count;

for (int j = 0; j < iCount; j++)
{
List<SampleItem> sampleItems = menus.Values[j];
sampleItems.Sort(SortByDisplayName);
}
}

/// <summary>
/// Add samples of categories in default categories
/// </summary>
private void AddSamplesToDefaultPulldownMenus()
{
int iCount = m_defaultMenus.Count;

// Sort sample items in every category by display name
SortSampleItemsInOneCategory(m_defaultMenus);

for (int i = 0; i < iCount; i++)
{
string category = m_defaultMenus.Keys[i];
List<SampleItem> sampleItems = m_defaultMenus.Values[i];
PulldownButton menuButton = m_pulldownButtons.Values[m_pulldownButtons.IndexOfKey(GetDisplayNameByEnumName(category))];
foreach (SampleItem item in sampleItems)
{
AddSampleToPulldownMenu(menuButton, item);
}
}
}

/// <summary>
/// Add samples of categories not in default categories
/// </summary>
private void AddCustomizedPulldownMenus()
{
int iCount = m_customizedMenus.Count;

// Sort sample items in every category by display name
SortSampleItemsInOneCategory(m_customizedMenus);

int i = 0;

while (iCount >= 3)
{
string name = m_customizedMenus.Keys[i++];
PulldownButtonData data1 = new PulldownButtonData(name, name);
name = m_customizedMenus.Keys[i++];
PulldownButtonData data2 = new PulldownButtonData(name, name);
name = m_customizedMenus.Keys[i++];
PulldownButtonData data3 = new PulldownButtonData(name, name);
IList<RibbonItem> buttons = m_panelRvtSamples.AddStackedItems(data1, data2, data3);
AddSamplesToStackedButtons(buttons);

iCount -= 3;
}

if (iCount == 2)
{
string name = m_customizedMenus.Keys[i++];
PulldownButtonData data1 = new PulldownButtonData(name, name);
name = m_customizedMenus.Keys[i++];
PulldownButtonData data2 = new PulldownButtonData(name, name);
IList<RibbonItem> buttons = m_panelRvtSamples.AddStackedItems(data1, data2);
AddSamplesToStackedButtons(buttons);
}
else if (iCount == 1)
{
string name = m_customizedMenus.Keys[i];
PulldownButtonData pulldownButtonData = new PulldownButtonData(name, name);
PulldownButton button = m_panelRvtSamples.AddItem(pulldownButtonData) as PulldownButton;
List<SampleItem> sampleItems = m_customizedMenus.Values[m_customizedMenus.IndexOfKey(button.Name)];
foreach (SampleItem item in sampleItems)
{
AddSampleToPulldownMenu(button, item);
}
}
}

/// <summary>
/// Add samples to corresponding pulldown button
/// </summary>
/// <param name="buttons">pulldown buttons</param>
private void AddSamplesToStackedButtons(IList<RibbonItem> buttons)
{
foreach (RibbonItem rItem in buttons)
{
PulldownButton button = rItem as PulldownButton;
List<SampleItem> sampleItems = m_customizedMenus.Values[m_customizedMenus.IndexOfKey(button.Name)];
foreach (SampleItem item in sampleItems)
{
AddSampleToPulldownMenu(button, item);
}
}
}
#endregion // Menu Helpers
}
}

SampleItem.cs

//
// (C) Copyright 2003-2019 by Autodesk, Inc.
//
// Permission to use, copy, modify, and distribute this software in
// object code form for any purpose and without fee is hereby granted,
// provided that the above copyright notice appears in all copies and
// that both that copyright notice and the limited warranty and
// restricted rights notice below appear in all supporting
// documentation.
//
// AUTODESK PROVIDES THIS PROGRAM "AS IS" AND WITH ALL FAULTS.
// AUTODESK SPECIFICALLY DISCLAIMS ANY IMPLIED WARRANTY OF
// MERCHANTABILITY OR FITNESS FOR A PARTICULAR USE. AUTODESK, INC.
// DOES NOT WARRANT THAT THE OPERATION OF THE PROGRAM WILL BE
// UNINTERRUPTED OR ERROR FREE.
//
// Use, duplication, or disclosure by the U.S. Government is subject to
// restrictions set forth in FAR 52.227-19 (Commercial Computer
// Software - Restricted Rights) and DFAR 252.227-7013(c)(1)(ii)
// (Rights in Technical Data and Computer Software), as applicable.
// 
using System;
using System.Collections.Generic;
using System.Text;
namespace RvtSamples
{
    /// <summary>
    /// The class contains information of a sample item to be added into samples menu
    /// </summary>
    public class SampleItem
    {
        #region Variables
        /// <summary>
        /// category
        /// </summary>
        private string m_category;
        /// <summary>
        /// display name
        /// </summary>
        private string m_displayName;
        /// <summary>
        /// path of large image
        /// </summary>
        private string m_largeImage;
        /// <summary>
        /// path of image
        /// </summary>
        private string m_image;
        /// <summary>
        /// description
        /// </summary>
        private string m_description;
        /// <summary>
        /// path of assembly
        /// </summary>
        private string m_assembly;
        /// <summary>
        /// class name
        /// </summary>
        private string m_className;
        #endregion
        #region Properties
        /// <summary>
        /// category
        /// </summary>
        public string Category
        {
            get 
            { 
                return m_category; 
            }
        }
        /// <summary>
        /// display name
        /// </summary>
        public string DisplayName
        {
            get 
            { 
                return m_displayName; 
            }
        }
        /// <summary>
        /// path of large image
        /// </summary>
        public string LargeImage
        {
            get 
            { 
                return m_largeImage; 
            }
        }
        /// <summary>
        /// path of image
        /// </summary>
        public string Image
        {
            get 
            { 
                return m_image; 
            }
        }
        /// <summary>
        /// description
        /// </summary>
        public string Description
        {
            get 
            { 
                return m_description; 
            }
        }
        /// <summary>
        /// path of assembly
        /// </summary>
        public string Assembly
        {
            get 
            { 
                return m_assembly; 
            }
        }
        /// <summary>
        /// class name
        /// </summary>
        public string ClassName
        {
            get 
            { 
                return m_className; 
            }
        }
        #endregion
        # region Methods
        /// <summary>
        /// Constructor
        /// </summary>
        public SampleItem()
        {
        }
        /// <summary>
        /// Constructor
        /// </summary>
        /// <param name="category">category</param>
        /// <param name="displayName">display name</param>
        /// <param name="description">description</param>
        /// <param name="largeImage">path of large image</param>
        /// <param name="image">path of image</param>
        /// <param name="assembly">path of assembly</param>
        /// <param name="className">class name</param>
        public SampleItem(string category, string displayName, string description, string largeImage, string image, string assembly, string className)
        {
            m_category = category;
            m_displayName = displayName;
            m_description = description;
            m_largeImage = largeImage;
            m_image = image;
            m_assembly = assembly;
            m_className = className;
        }
        #endregion
    }
}