Monthly Archives: April 2014

WPF TemplateSelector for contentTemplate

I wanted to dynamically change template of the tab content based on the tab selected. I used ContentTemplateSelector. It’s so simple:
Write a custom template selector inheriting DataTemplateSelector and override SelectTemplate method

    public class CustomTabItemSelector
        : DataTemplateSelector
    {
        public override System.Windows.DataTemplate SelectTemplate(object item, System.Windows.DependencyObject container)
        {
            FrameworkElement element = container as FrameworkElement;
            if (element != null && item != null && item is object)
            {
                if (item.ToString().ToLower() == "related" || item.ToString().ToLower() == "linked")
                    return element.FindResource("TabContentQuestionDetails") as DataTemplate;
                else if(item.ToString().ToLower() == "comments")
                    return element.FindResource("TabContentComments") as DataTemplate;
                else
                    return element.FindResource("TabContentAnswers") as DataTemplate;
                
            }
            return null;
        }
    }

You need to declare DataTemplates in the ResourceDictionary or in the window resources or any where the element can be able to find the resource

    <DataTemplate x:Key="TabContentQuestions">
            <telerik:RadGridView
                             ItemsSource="{Binding DataContext.Questions, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}"
                             Height="300" Width="Auto"
                             AutoGenerateColumns="False"
                            x:Name="QuestionGrid" AllowDrop="False"
                             >
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn Header="Title" DataMemberBinding="{Binding Title}"/>
                </telerik:RadGridView.Columns>
                <i:Interaction.Triggers>
                    <i:EventTrigger EventName="PreviewMouseLeftButtonDown">
                        <i:InvokeCommandAction Command="{Binding DataContext.SelectedQuestionCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}}" CommandParameter="{Binding ElementName=QuestionGrid, Path=SelectedItem}">

                        </i:InvokeCommandAction>
                    </i:EventTrigger>
                </i:Interaction.Triggers>
            </telerik:RadGridView>
        </DataTemplate>

you need to add the reference to the customtemplateselector assembly and declare it in the xaml

//refering the assembly
 xmlns:ts="clr-namespace:SomeAssemblyNamespace;assembly:SomeReferencingAssemblyName"

//Declare the customselector
<ts:CustomTabItemSelector x:Key="myCustomTabItemSelector"/>

//Using the selector in the tabcontrol
<telerik:RadTabControl x:Name="SomeTab"
                       ContentTemplateSelector="{StaticResource myCustomTabItemSelector}"

Powershell module to MapNetworkDrive

At my work, every few days I have to change the user and connect to a network drive. The mapping process every time used to be little bit difficult. I have created some powershell modules which helped me in this process. This is for my reference and if it helps others that’s great:
I have powershell 2.0 so the modules need to be created in VS 2008 for binary type modules, one can create powershell scripts and imports them as modules too. I wrote it in VS 2008, you need to add reference to System.Management and System.Management.Automation.dll(this is in powershell folder).

I wrote 4 different commandlets in this module, each will perform a different functionality.
Get-Drives – Gets all the logical drives and network paths
Get-FreeDriveLetter – Gets the available drive letter in the descending order which can be used.
Map-AuthNetworkDrive – Maps the network drive with the provided credentials or default credentials
Map-DisconnectNetworkDrive – Removes the map

Get-Drives

    [Cmdlet(VerbsCommon.Get, "Drives")]
    public class GetDrives: PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                var drives = CommonMethods.GetDrives();

                this.WriteObject(drives, true);
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.NotImplemented, null));
            }

        }
               
    }

    //CommonMethods.GetDrives
 internal static IEnumerable<object> GetDrives2()
        {
            IList<object> driveInfo = new List<object>();
            try
            {
                SelectQuery query = new SelectQuery("Select DeviceID, DriveType, ProviderName From Win32_LogicalDisk");
                ManagementObjectSearcher searcher = new ManagementObjectSearcher(query);
                foreach(ManagementObject disk in searcher.Get())
                {
                    driveInfo.Add(new { DeviceID = disk["DeviceID"], DriveType = (DiskType)disk["DriveType"], ProviderName = disk["ProviderName"] });
                }
            }
            catch (Exception ex)
            {
                throw ex;

            }

            return driveInfo;
        }

  public enum DiskType : uint
    {
        Unknown = 0,
        RemovableDisk = 2,
        LocalDisk = 3,
        NetworkDrive = 4,
        CompactDisk = 5,
        RAMDisk = 6
    }

Get-FreeDriveLetter

   [Cmdlet(VerbsCommon.Get, "FreeDriveLetter")]
    public class GetFreeDriveLetter : PSCmdlet
    {
        protected override void ProcessRecord()
        {
            try
            {
                string freeDrive = CommonMethods.GetFreeDriveLetter();

                this.WriteObject(freeDrive);
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.NotImplemented, null));
            }
        }
    }

   //in CommonMethods.GetFreeDriveLetter method
      internal static string GetFreeDriveLetter()
        {
            string freeDrive = "";
            string[] driveLetters = { "D:", "E:", "F:", "G:", "H:", "I:", "J:", "K:", "L:", "M:", "N:", "O:", "P:", "Q:", "R:", "S:", "T:", "U:", "V:", "W:", "X:", "Y:", "Z:" };
            var drives = System.IO.DriveInfo.GetDrives().Select(x => x.Name.Replace("\\", ""));
       
            foreach (var s in driveLetters.Reverse())
            {
                if (drives.Contains(s))
                {
                    freeDrive = "";
                }
                else
                {
                    freeDrive = s;
                    break;
                }
            }

            return freeDrive;
        }

For map and unmap I used Windows Script Host object model reference(IWshRuntimeLibrary)

     [Cmdlet("Map","AuthNetworkDrive")]
    public class MapNetworkDrive: PSCmdlet
    {
        [Parameter(Mandatory=true, Position=0,ValueFromPipeline=false)]
        public string UNCPath { get; set; }

        [Parameter(Mandatory=false, Position=1)]
        public PSCredential Credential { get; set; }

        protected override void ProcessRecord()
        {
            try
            {
                WshNetwork network = new WshNetwork();
                if (Credential == null)
                {
                    network.MapNetworkDrive(CommonMethods.GetFreeDriveLetter(), UNCPath, false);
                }
                else
                {
                    network.MapNetworkDrive(CommonMethods.GetFreeDriveLetter(), UNCPath, true, Credential.UserName, Credential.GetNetworkCredential().Password);
                }
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001",ErrorCategory.MetadataError, null));
            }
        }
    }

    [Cmdlet("Map", "DisconnectNetworkDrive")]
    public class UnMapNetworkDrive : PSCmdlet
    {
        [Parameter(Mandatory=true, Position=0)]
        public string DriveName { get; set; }

        protected override void ProcessRecord()
        {

            try
            {
                
                    IWshRuntimeLibrary.WshNetwork network = new IWshRuntimeLibrary.WshNetwork();
                    network.RemoveNetworkDrive(DriveName, true, true);
                
            }
            catch (Exception ex)
            {
                this.WriteError(new ErrorRecord(ex, "1001", ErrorCategory.MetadataError, null));
            }
        }
    }

Once the build, you can import the module from powershell ise

Import-Module 'module dll path'

this will be available for that session. One can copy to the powershell module path, so that it can be available all the time.