Intersoft ClientUI 8 > ClientUI Controls > Control Library > Navigation Controls Overview > UXBreadCrumb > UXBreadCrumb How-to Topics > How-to: Use UXBreadCrumb for Advanced Scenarios |
This example will demonstrate how to configure UXBreadCrumb in advanced scenario where the TargetFrame is not specified. Although the control is primarily designed for page navigation, it can also be customized to achieve more advanced scenarios such as in File Explorer. For more information about the control usage in page navigation, see How-to: Use UXBreadCrumb for Page Navigation.
In this example, the UXBreadCrumb is used to populate data from a XML file based on the current path. This means that the data grid will be refreshed every time users navigate to a different location through the breadcrumb control. Likewise, when users double click on the data grid, the UXBreadCrumb control will be synchronized as well. The following tutorial guides you how to implement this scenario.
This example takes code from the technical sample project SL5.ClientUI.2012R2.Preview, File Explorer sample.
FileExplorer.xaml |
Copy Code
|
---|---|
<Intersoft:UXPage xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" xmlns:Intersoft="http://intersoft.clientui.com/schemas" xmlns:local="clr-namespace:ClientUI._2012R2.Preview.Views.UXBreadCrumb" xmlns:ViewModels="clr-namespace:ClientUI._2012R2.Preview.ViewModels" Style="{StaticResource HomeSampleStyle}" x:Class="ClientUI._2012R2.Preview.Views.UXBreadCrumb.FileExplorer" Title="FileExplorer Page" d:DesignWidth="640" d:DesignHeight="480"> <Intersoft:UXPage.DataContext> <ViewModels:FileExplorerViewModel /> </Intersoft:UXPage.DataContext> <Intersoft:UXPage.Resources> </Intersoft:UXPage.Resources> <Grid x:Name="LayoutRoot"> <Intersoft:StylishLabel Style="{StaticResource InfoStyle}" VerticalAlignment="Bottom"> <TextBlock TextWrapping="Wrap"> <Run Text="UXBreadCrumb is a versatile navigation control that allows users to easily navigate between pages, with the familiar look of Windows Explorer navigation. UXBreadCrumb combines the address bar and menu functionality in an elegant single interface, enabing users to perform navigation in simple point-and-click manner."/> <LineBreak/> <LineBreak/> <Run Text="In addition to page navigation, UXBreadCrumb also supports load-on-demand to address the most demanding business application scenarios. In this sample, the UXBreadCrumb doesn't load data initially since the structure is dynamically loaded as user navigates to a specific folder. This sample also simulates the asynchronous data retrieval process to show the user interface properly."/> </TextBlock> </Intersoft:StylishLabel> <Intersoft:UXWindow Header="UXBreadCrumb - Load on Demand sample" Width="560" Height="350" Background="#FFF8F8F8" ContentBorderBrush="{x:Null}" CanMinimize="False" CanMaximize="False" Icon="/ClientUI.2012R2.Preview;component/Assets/Icons/UXBreadCrumb.16x16.png" Left="80" Top="80" IsClientVisible="True" IsActive="True" VerticalAlignment="Top" HorizontalAlignment="Left" Margin="80,80,0,0" CanMove="False"> <Intersoft:DockPanel Style="{StaticResource DockPanelStyle}" Margin="4"> <Intersoft:UXBreadCrumb Intersoft:DockPanel.Dock="Top" ItemsSource="{Binding BreadCrumbItems}" DisplayMemberPath="DisplayName" NavigateUriMemberPath="NavigateUri" ImageMemberPath="Icon" CollectionMemberPath="Children" IsRootVisible="True" RootName="Corporate Files" RootUri="/" RootIcon="/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png" IsLoadOnDemand="True" ExpandedItem="{Binding ExpandedItem, Mode=TwoWay}" IsRefreshButtonVisible="False" ProcessedItem="{Binding ProcessedItem, Mode=TwoWay}" NavigateCommand="{Binding NavigateCommand}" QueryText="{Binding QueryText, Mode=TwoWay}" QueryResult="{Binding QueryResult, Mode=TwoWay}" /> <Intersoft:UXGridView Intersoft:DockPanel.IsFillElement="True" ItemsSource="{Binding GridItems}" AutoGenerateColumns="False" DoubleClickCommand="{Binding DoubleClickCommand}" Margin="0,12,0,0"> <Intersoft:UXGridView.Columns> <Intersoft:UXGridViewTextColumn Header="Name" Binding="{Binding Name}" DisplayMode="ContentAndImage" ImageBinding="{Binding Icon}" /> <Intersoft:UXGridViewTextColumn Header="Date Modified" Binding="{Binding Date}" /> <Intersoft:UXGridViewTextColumn Header="Type" Binding="{Binding Type}" /> <Intersoft:UXGridViewTextColumn Header="Size" Binding="{Binding Size}" /> </Intersoft:UXGridView.Columns> </Intersoft:UXGridView> </Intersoft:DockPanel> </Intersoft:UXWindow> </Grid> </Intersoft:UXPage> |
In the sample code above, neither Sitemap nor TargetFrame is set., only the ItemsSource property is set. In this scenario, the NavigateCommand is also bound to ICommand in the view model. This is to detect changes in the "navigated" path and so that UXBreadCrumb can refresh accordingly. This sample also incorporates load on demand technique. To learn more about how to UXBreadCrumb for load-on-demand scenarios, see How-to: Enable Load on Demand for UXBreadCrumb.
FolderSitemap.xml |
Copy Code
|
---|---|
<?xml version="1.0" encoding="utf-8" ?> <Sitemap> <SitemapData> <DisplayName>Corporate Files</DisplayName> <Path>/</Path> <Type>File folder</Type> <Children> <SitemapData> <DisplayName>Design</DisplayName> <Path>/Design</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Live Sample</DisplayName> <Path>/Design/Live Sample</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Sample Scenarios</DisplayName> <Path>/Design/Live Sample/Sample Scenarios.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>28 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>BreadCrumb Sample1</DisplayName> <Path>/Design/Live Sample/BreadCrumb Sample1.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>14 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>BreadCrumb Sample2</DisplayName> <Path>/Design/Live Sample/BreadCrumb Sample2.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>15 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>BreadCrumb Sample3</DisplayName> <Path>/Design/Live Sample/BreadCrumb Sample3.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>16 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>BreadCrumb Samples</DisplayName> <Path>/Design/Live Sample/BreadCrumb Samples.psd</Path> <Type>Adobe Photoshop File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>795 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/psd.png</Icon> </SitemapData> </Children> </SitemapData> <SitemapData> <DisplayName>Newsletter</DisplayName> <Path>/Design/Newsletter</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>September2012_draft</DisplayName> <Path>/Design/Newsletter/September2012_draft.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>24 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>October2012_draft</DisplayName> <Path>/Design/Newsletter/October2012_draft.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>26 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>November2012_draft</DisplayName> <Path>/Design/Newsletter/November2012_draft.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>25 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>December2012_draft</DisplayName> <Path>/Design/Newsletter/December2012_draft.jpg</Path> <Type>JPG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>24 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> <SitemapData> <DisplayName>Newsletter_banner</DisplayName> <Path>/Design/Newsletter/Newsletter_banner.psd</Path> <Type>Adobe Photoshop File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>800 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/psd.png</Icon> </SitemapData> <SitemapData> <DisplayName>NL contents</DisplayName> <Path>/Design/Newsletter/NL contents.rar</Path> <Type>WinRAR Archive</Type> <Date>12/01/2012 4:06 PM</Date> <Size>500 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/rar.png</Icon> </SitemapData> </Children> </SitemapData> <SitemapData> <DisplayName>Release Task Design Checklist</DisplayName> <Path>/Design/Release Task Design Checklist.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>16 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Company Logo</DisplayName> <Path>/Design/Company Logo.png</Path> <Type>PNG File</Type> <Date>12/01/2012 4:06 PM</Date> <Size>55 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/img.png</Icon> </SitemapData> </Children> </SitemapData> <SitemapData> <DisplayName>Marketing</DisplayName> <Path>/Marketing</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Marketing Plan Template</DisplayName> <Path>/Marketing/Marketing Plan Template.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>50 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Latest Product List</DisplayName> <Path>/Marketing/Latest Product List.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>50 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Action Plan 2012</DisplayName> <Path>/Marketing/Action Plan 2012.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>42 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>List of Marketing Task</DisplayName> <Path>/Marketing/List of Marketing Task.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>30 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Newsletter Writing Guideline</DisplayName> <Path>/Marketing/Newsletter Writing Guideline.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>30 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Product Writing Guideline</DisplayName> <Path>/Marketing/Product Writing Guideline.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>24 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> </Children> </SitemapData> <SitemapData> <DisplayName>Human Resource</DisplayName> <Path>/Human Resource</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>HR Reports</DisplayName> <Path>/Human Resource/HR Reports</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Client Visit</DisplayName> <Path>/Human Resource/HR Reports/Client Visit</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Designer_visit_log</DisplayName> <Path>/Human Resource/HR Reports/Client Visit/Designer_visit_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>16 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Developer_visit_log</DisplayName> <Path>/Human Resource/HR Reports/Client Visit/Developer_visit_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>20 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Sales_visit_log</DisplayName> <Path>/Human Resource/HR Reports/Client Visit/Sales_visit_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>40 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Support_visit_log</DisplayName> <Path>/Human Resource/HR Reports/Client Visit/Support_visit_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>40 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> </Children> </SitemapData> <SitemapData> <DisplayName>Claim Expenses</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Designer_claims</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Designer_claims.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>33 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Developer_claims</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Developer_claims.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>24 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Sales_claims</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Sales_claims.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>49 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Support_claims</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Support_claims.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>47 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Office expenses</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Office expenses.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>41 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Designer_overtime_log</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Designer_overtime_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>35 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Developer_overtime_log</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Developer_overtime_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>41 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Sales_overtime_log</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Sales_overtime_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>16 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Support_overtime_log</DisplayName> <Path>/Human Resource/HR Reports/Claim Expenses/Support_overtime_log.xlsx</Path> <Type>Microsoft Excel Worksheet</Type> <Date>12/01/2012 4:06 PM</Date> <Size>88 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/xlsx.png</Icon> </SitemapData> </Children> <SitemapData> <DisplayName>Daily Report</DisplayName> <Path>/Human Resource/HR Reports/Daily Report.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>100 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Petty Cash Expense</DisplayName> <Path>/Human Resource/HR Reports/Petty Cash Expense.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>150 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Vacancies2012</DisplayName> <Path>/Human Resource/HR Reports/Vacancies2012.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>200 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> </SitemapData> </Children> <SitemapData> <DisplayName>Activity_SeniorDeveloper</DisplayName> <Path>/Human Resource/Activity_SeniorDeveloper.pdf</Path> <Type>Adobe Acrobat Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>1.1 MB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/pdf.png</Icon> </SitemapData> <SitemapData> <DisplayName>Activity_SeniorUIUXDesigner</DisplayName> <Path>/Human Resource/Activity_SeniorUIUXDesigner.pdf</Path> <Type>Adobe Acrobat Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>1.2 MB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/pdf.png</Icon> </SitemapData> <SitemapData> <DisplayName>Activity_Support</DisplayName> <Path>/Human Resource/Activity_Support.pdf</Path> <Type>Adobe Acrobat Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>1.6 MB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/pdf.png</Icon> </SitemapData> <SitemapData> <DisplayName>December Work Plan</DisplayName> <Path>/Human Resource/December Work Plan.pdf</Path> <Type>Adobe Acrobat Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>2.1 MB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/pdf.png</Icon> </SitemapData> </SitemapData> </Children> </SitemapData> <SitemapData> <DisplayName>Shared Documents</DisplayName> <Path>/Shared Documents</Path> <Type>File folder</Type> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/folderIcon.png</Icon> <Children> <SitemapData> <DisplayName>Travel_policy</DisplayName> <Path>/Shared Documents/Travel_policy.pdf</Path> <Type>Adobe Acrobat Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>600 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/pdf.png</Icon> </SitemapData> <SitemapData> <DisplayName>Essential_KPI</DisplayName> <Path>/Shared Documents/Essential_KPI.pdf</Path> <Type>Adobe Acrobat Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>410 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/pdf.png</Icon> </SitemapData> <SitemapData> <DisplayName>CI01-Overtime_form</DisplayName> <Path>/Shared Documents/CI01-Overtime_form.docx</Path> <Type>Microsoft Word Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>34 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/docx.png</Icon> </SitemapData> <SitemapData> <DisplayName>Organization_structure</DisplayName> <Path>/Shared Documents/Organization_structure.xlsx</Path> <Type>Microsoft Visio Document</Type> <Date>12/01/2012 4:06 PM</Date> <Size>400 KB</Size> <Icon>/ClientUI.2012R2.Preview;Component/Assets/Icons/vsdx.png</Icon> </SitemapData> </Children> </SitemapData> </Children> </SitemapData> </Sitemap> |
This is the example folder structure used in the File Explorer sample. This XML mainly consists of SitemapData, which may have children, DisplayName, Path that is used to notify the UXBreadCrumb of changes, Size, and Icon property. The view model will give much clearer understanding how the File Explorer sample works.
FileItem.cs |
Copy Code
|
---|---|
using System; namespace ClientUI._2012R2.Preview.DomainModel { public class FileItem : ModelBase { private DateTime _date; private int _folderId; private Uri _icon; private string _name; private string _size; private string _type; private Uri _uri; public int FolderId { get { return this._folderId; } set { if (this._folderId != value) { this._folderId = value; OnPropertyChanged("FolderId"); } } } public Uri Icon { get { return this._icon; } set { if (this._icon != value) { this._icon = value; OnPropertyChanged("Icon"); } } } public string Name { get { return this._name; } set { if (this._name != value) { this._name = value; OnPropertyChanged("Name"); } } } public DateTime Date { get { return this._date; } set { if (this._date != value) { this._date = value; OnPropertyChanged("Date"); } } } public string Size { get { return this._size; } set { if (this._size != value) { this._size = value; OnPropertyChanged("Size"); } } } public string Type { get { return this._type; } set { if (this._type != value) { this._type = value; OnPropertyChanged("Type"); } } } public Uri Uri { get { return this._uri; } set { if (this._uri != value) { this._uri = value; OnPropertyChanged("Uri"); } } } } } |
This is the FileItem model on which the FolderSitemap.xml will be parsed into.
FileExplorerViewModel.cs |
Copy Code
|
---|---|
using System; using System.Collections; using System.Collections.Generic; using System.Collections.ObjectModel; using System.ComponentModel; using System.Linq; using System.Threading; using System.Windows; using System.Windows.Input; using System.Windows.Resources; using System.Xml.Linq; using ClientUI._2012R2.Preview.DomainModel; using Intersoft.Client.Data.ComponentModel; using Intersoft.Client.Framework; using Intersoft.Client.Framework.Input; using Intersoft.Client.UI.Navigation; namespace ClientUI._2012R2.Preview.ViewModels { public class FileExplorerViewModel : ViewModelBase { #region Constructor public FileExplorerViewModel() { this.PathToNavigate = "/Human Resource/HR Reports/Client Visit"; StreamResourceInfo resourceStream = Application.GetResourceStream(new Uri(this.XMLDocumentPath, UriKind.Relative)); if (resourceStream != null) this.XMLDocument = XDocument.Load(resourceStream.Stream, LoadOptions.SetBaseUri); this.BreadCrumbItems = new ObservableCollection<SitemapData>(); this.DoubleClickCommand = new DelegateCommand(DoubleClick); this.NavigateCommand = new DelegateCommand(Navigate); if (!string.IsNullOrEmpty(this.PathToNavigate)) { this.FindNode(this.PathToNavigate); this.LoadItemsFromCurrentNode(); } } #endregion #region Fields private object _expandedItem; private IEnumerable _gridItems; private string _pathToNavigate; private object _processedItem; private object _queryResult; private string _queryText; private IEnumerable<SitemapData> _sitemapData; #endregion #region Properties public BackgroundWorker BackgroundWorker { get; set; } public ObservableCollection<SitemapData> BreadCrumbItems { get; set; } public XElement CurrentNode { get; set; } public ICommand DoubleClickCommand { get; set; } public ICommand NavigateCommand { get; set; } public XDocument XMLDocument { get; set; } public string XMLChildrenPath = "Children"; public string XMLDatePath = "Date"; public string XMLDisplayNamePath = "DisplayName"; public string XMLDocumentPath = "/ClientUI.2012R2.Preview;Component/Assets/Xml/FolderSitemap.xml"; public string XMLIconPath = "Icon"; public string XMLNavigationPath = "Path"; public string XMLSizePath = "Size"; public string XMLTypePath = "Type"; void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e) { } void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e) { BackgroundWorker worker = sender as BackgroundWorker; if (worker != null) { SitemapData obj = e.Argument as SitemapData; if (obj != null) { var dataThread = new Thread(() => { Thread.Sleep(1000); CrossPlatform.BeginInvoke(new Action(() => { if (!worker.CancellationPending) { this._sitemapData = this.SearchSitemap(obj); IEnumerable<SitemapData> sitemapDatas = this._sitemapData as IList<SitemapData> ?? this._sitemapData.ToList(); if (this._sitemapData != null && sitemapDatas.Any()) obj.Children = sitemapDatas; this.ProcessedItem = obj; } })); }); dataThread.Start(); } } } public object ExpandedItem { get { return this._expandedItem; } set { if (this.BackgroundWorker != null) { this.BackgroundWorker.DoWork -= BackgroundWorker_DoWork; this.BackgroundWorker.RunWorkerCompleted -= BackgroundWorker_RunWorkerCompleted; this.BackgroundWorker.CancelAsync(); this.BackgroundWorker = null; } if (this._expandedItem != value) { this._expandedItem = value; SitemapData obj = value as SitemapData; if (obj != null) { this.BackgroundWorker = new BackgroundWorker { WorkerSupportsCancellation = true }; this.BackgroundWorker.DoWork += BackgroundWorker_DoWork; this.BackgroundWorker.RunWorkerCompleted += BackgroundWorker_RunWorkerCompleted; this.BackgroundWorker.RunWorkerAsync(obj); } OnPropertyChanged("ExpandedItem"); } } } public object ProcessedItem { get { return this._processedItem; } set { if (this._processedItem != value) { this._processedItem = value; OnPropertyChanged("ProcessedItem"); } } } public object QueryResult { get { return this._queryResult; } set { if (this._queryResult != value) { this._queryResult = value; OnPropertyChanged("QueryResult"); } } } public string QueryText { get { return this._queryText; } set { if (this._queryText != value) { this._queryText = value; var dataThread = new Thread(() => { //testing purposes Thread.Sleep(500); CrossPlatform.BeginInvoke(new Action(() => { this.QueryResult = this.TraverseElementsAndFindPath(this._queryText); })); }); dataThread.Start(); } else { this._queryText = value; } OnPropertyChanged("QueryText"); } } public IEnumerable GridItems { get { return this._gridItems; } set { if (this._gridItems != value) { this._gridItems = value; OnPropertyChanged("GridItems"); } } } public string PathToNavigate { get { return this._pathToNavigate; } set { if (value != null) { this._pathToNavigate = value; this.FindNode(this._pathToNavigate); this.LoadItemsFromCurrentNode(); } } } #endregion #region Methods #region ICommand private void DoubleClick(object parameter) { FileItem fileItem = parameter as FileItem; if (fileItem != null && fileItem.Uri != null && fileItem.Type == "File folder") this.PathToNavigate = fileItem.Uri.OriginalString; } private void Navigate(object parameter) { if (parameter is SitemapData) { SitemapData data = parameter as SitemapData; if (data.NavigateUri != null && !string.IsNullOrEmpty(data.NavigateUri.OriginalString)) this.PathToNavigate = data.NavigateUri.OriginalString; } if (parameter is Uri) { Uri uri = parameter as Uri; if (!string.IsNullOrEmpty(uri.OriginalString)) this.PathToNavigate = uri.OriginalString; } } #endregion private FileItem CreateFileItem(XContainer element, string displayNamePath, string navigateUriPath, string iconPath, string typePath, string datePath, string sizePath) { FileItem fileItem = new FileItem(); if (element.Element(displayNamePath) != null && element.Element(displayNamePath).Value != null) fileItem.Name = element.Element(displayNamePath).Value; if (element.Element(navigateUriPath) != null && element.Element(navigateUriPath).Value != null) fileItem.Uri = new Uri(element.Element(navigateUriPath).Value, UriKind.RelativeOrAbsolute); if (element.Element(iconPath) != null && element.Element(iconPath).Value != null) fileItem.Icon = new Uri(element.Element(iconPath).Value, UriKind.RelativeOrAbsolute); if (element.Element(typePath) != null && element.Element(typePath).Value != null) fileItem.Type = element.Element(typePath).Value; if (element.Element(datePath) != null && element.Element(datePath).Value != null) fileItem.Date = Convert.ToDateTime(element.Element(datePath).Value); if (element.Element(sizePath) != null && element.Element(sizePath).Value != null) fileItem.Size = element.Element(sizePath).Value; return fileItem; } private SitemapData CreateSitemapData(XContainer element, string displayNamePath, string navigateUriPath, string iconPath) { if (element.Element(this.XMLTypePath) != null && element.Element(this.XMLTypePath).Value == "File folder") { SitemapData sitemap = new SitemapData(); if (element.Element(displayNamePath) != null && element.Element(displayNamePath).Value != null) sitemap.DisplayName = element.Element(displayNamePath).Value; if (element.Element(navigateUriPath) != null && element.Element(navigateUriPath).Value != null) sitemap.NavigateUri = new Uri(element.Element(navigateUriPath).Value, UriKind.RelativeOrAbsolute); if (element.Element(iconPath) != null && element.Element(iconPath).Value != null) sitemap.Icon = new Uri(element.Element(iconPath).Value, UriKind.RelativeOrAbsolute); return sitemap; } return null; } private void FindNode(string path) { if (this.XMLDocument == null || string.IsNullOrEmpty(path)) return; this.FindNodesRecursive(this.XMLDocument.Elements().SelectMany(e => e.Elements()), path); } private void FindNodesRecursive(IEnumerable<XElement> elements, string path) { foreach (XElement element in elements) { XElement node = element.Element(this.XMLNavigationPath); if (node != null) { if (node.Value == path) { this.CurrentNode = node.Parent; break; } if (element.Element(this.XMLChildrenPath) != null) { this.FindNodesRecursive(element.Element(this.XMLChildrenPath).Elements(), path); } } } } private void FindParentsRecursive(XObject element) { XElement parent = element.Parent; if (parent != null) { if (parent.Name == "SitemapData" && parent.Parent != null && parent.Parent.Name == this.XMLChildrenPath) this.BreadCrumbItems.Insert(0, this.CreateSitemapData(parent, this.XMLDisplayNamePath, this.XMLNavigationPath, this.XMLIconPath)); this.FindParentsRecursive(parent); } } private IEnumerable<SitemapData> TraverseElementsAndFindPath(string queryText) { if (this.XMLDocument == null) return null; ObservableCollection<SitemapData> sitemap = new ObservableCollection<SitemapData>(); foreach (XElement descendant in this.XMLDocument.Descendants(this.XMLNavigationPath).Where(descendant => descendant.Value.StartsWith(queryText) && descendant.Parent != null)) { SitemapData data = this.CreateSitemapData(descendant.Parent, this.XMLDisplayNamePath, this.XMLNavigationPath, this.XMLIconPath); if (data != null) sitemap.Add(data); } return sitemap; } private void LoadBreadCrumbItems() { if (this.CurrentNode == null) return; this.BreadCrumbItems.Clear(); XElement root = this.XMLDocument.Elements().Elements().FirstOrDefault(); if (root != null) { string rootUri = root.Element(this.XMLNavigationPath).Value; if (this.PathToNavigate != rootUri) this.BreadCrumbItems.Insert(0, this.CreateSitemapData(this.CurrentNode, this.XMLDisplayNamePath, this.XMLNavigationPath, this.XMLIconPath)); } this.FindParentsRecursive(this.CurrentNode); } private void LoadGridItems() { if (this.CurrentNode == null) return; ObservableCollection<FileItem> collection = new ObservableCollection<FileItem>(); if (this.CurrentNode.Element(this.XMLChildrenPath) != null) { foreach (XElement element in this.CurrentNode.Element(this.XMLChildrenPath).Elements()) { collection.Add(this.CreateFileItem(element, this.XMLDisplayNamePath, this.XMLNavigationPath, this.XMLIconPath, this.XMLTypePath, this.XMLDatePath, this.XMLSizePath)); } } this.GridItems = new PagedCollectionView(collection); } private void LoadItemsFromCurrentNode() { if (this.CurrentNode != null) { this.LoadBreadCrumbItems(); this.LoadGridItems(); } } private IEnumerable<SitemapData> SearchSitemap(SitemapData sitemapData) { if (sitemapData != null && sitemapData.NavigateUri != null) this.FindNode(sitemapData.NavigateUri.OriginalString); ObservableCollection<SitemapData> collection = new ObservableCollection<SitemapData>(); IEnumerable<XElement> elements = this.CurrentNode.Elements(); foreach (SitemapData sitemap in (from element in elements where element.Name == this.XMLChildrenPath from el in element.Elements() select el).Select(el => this.CreateSitemapData(el, this.XMLDisplayNamePath, this.XMLNavigationPath, this.XMLIconPath)).Where(sitemap => sitemap != null)) { collection.Add(sitemap); } return collection; } #endregion } } |
The main entry point is the Navigate method. When PathToNavigate raises OnPropertyChanged event, the view model finds the appropriate node in the physical XML file. Once the correct node is found, traverse upwards and find each parent and put them in an ObservableCollection<SitemapData>which will be then used as the ItemsSource for UXBreadCrumb. This is the algorithm to refresh the UXBreadCrumb without using neither Sitemap data nor TargetFrame.