WPF – Panel Slide-In Animation From Left Or Right Side

Button Click Slides in Panel


Create a panel which slides in from the right when a button is clicked. The second goal is to have it all done in Xaml with no codebehind code. This article describes how to do that and explains the process behind what is needed in a step by step process. Page #2 below has a link to the full code if one does not need the explanation.


The picture here shows the final code in action where a ToggleButton switches it’s state (IsChecked) between true and false. When that state changes to true it will have the panel slide in from the right and false will have it slide back.

The process described below can be done by placing the code snippets in Xaml and switching to the Design view of Visual Studio.

Un-Moved Rectangle in Design Mode with and without TranslateTransform

The Panel is a Blue Rectangle

For the example we will use a basic Rectangle and place it on the screen in a plain Grid. The panel will be blue an it will reside on the right side of the screen. Here is the initial code, note in future code examples I will omit the Marigin and the alignments for the sake of brevity; but those omitions are needed and will be required in the final code.

    <Rectangle Fill="Blue" Width="100" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,0,0"  />

Not Understanding TranslateTransform Is The First Hurdle

When researching and applying the concepts found, I did not understand the importance of TranslateTransform coordinates in this process. When I learned about this concept, other things fell into place.

What TranslateTransform process is, is that each object on the screen has a location, and that location is it’s anchor, so to speak. When one changes the TranslateTransform of an object, it moves it off its anchor and can be shifted right, left, up, or down by changes X and Y values from that initial position.

To achieve movement as mentioned one must provide the initial anchor point to the Rectangle. Below is a non-moved anchoring of the panel at "0,0" so it will appear the on the screen with 0 movement(s).

<Rectangle ...>
       <TranslateTransform X="0" Y="0" />

Start it off the screen

Image moved 100 X pixels off its Anchor as shown in Design Mode

What we need now is to, adjust what we have, but start it out of sight to the right *side* of the screen. To achieve this we will change the above translate transform coordinates to instead move the X value and have the start in the off page position. To do that change the existing to this:

<TranslateTransform X="100" Y="0" />

Play with it in design mode by changing the X and Y values and not how it moves around from its initial anchor point.

Set Associative Values

Currently our panel has a Width of 100 and we want to move it off the screen, *and move it back* by that amount; an offset slide amount. What we will do is in the Grid Resource section, *though it could be placed in the page’s Resource section*, is a constant which we will apply to the panel’s Width and the X as an initial offset value.

            <system:Double x:Key="SlideOffSet">100</system:Double>

        <Rectangle Width="{StaticResource SlideOffSet}" Height="100" HorizontalAlignment="Right" VerticalAlignment="Top" Margin="0,10,0,0" >
                <TranslateTransform X="{StaticResource SlideOffSet}" Y="0" />

Check the design mode…it should still be off the screen and in the same dimensions as specified in the previous section.

Add a ToggleButton To Change States

We’ve added a toggle button which centers itself and reports its check status

We add a toggle button above the Rectangle panel because we want the panel to be drawn last; so to have it have the highest Zindex. So when it slides in, it will be above all other controls.

    <ToggleButton Height="30" Width="60" Margin="0,20,0,20" x:Name="SlideState">
        <TextBlock Text="{Binding IsChecked, ElementName=SlideState}"
                       VerticalAlignment="Center" HorizontalAlignment="Center"  >

    <Rectangle ...

The Animation Magic To Move It In and Out

To do this we will use Storyboards which when triggered will change the panel’s TranslateTransform X value to and from our slide offset. Go ahead and add the StoryBoards below under the SlideOffset setting in the Resources section.

<Storyboard x:Key="SlideRight">
    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                     From="0" To="{StaticResource SlideOffSet}"
                     Duration="0:0:0.3" />

<Storyboard x:Key="SlideLeft">
    <DoubleAnimation Storyboard.TargetProperty="(UIElement.RenderTransform).(TranslateTransform.X)"
                     From="{StaticResource SlideOffSet}" To="0" 
                     Duration="0:0:0.3" />

The above code basically changes the target control, in our case the Rectangle, and shifts the X transform anchor value.

Initiate The Dark Move Magic On Button Click

Believe it or not, but we are not finished. The final bit of code has us, again, putting code in the Resource section which will define a style for our Rectangle.

This style is a trigger which is based, bound, off of the value of the IsChecked and depending on its value, initiates the SlideLeft (to move into view) and the SlideRight to move it back off the screen.

<Style TargetType="{x:Type Rectangle}">
        <DataTrigger Binding="{Binding IsChecked, ElementName=SlideState}" Value="True">
                <BeginStoryboard Storyboard="{StaticResource SlideLeft}" />
                <BeginStoryboard Storyboard="{StaticResource SlideRight}" />

Final Thoughts & Code

On the following page (#2) is the full code for your perusal, with no changes from above. For me learning how to position a panel off the screen and then move it was trial and error of internet searches and reading StackOverflow posts. Each component on its own is understandable, but has to be consumed in a certain order. This post is that order in which I would have liked to have read first.

To further your understanding of this see Transforms Overview on Microsoft’s documentation.

Full Code on Page 2 —-(*if link to page #2 is not seen below, load the whole article and scroll down*)——–>


Copy Directory Files and Create Random Names In PowerShell

I had a need to take an existing directory with a specific set of files and create new copies of those files, but with new random names. These new files would test a process which needed a lot of files to be loaded and the files had to be of a specific format and data such as a zip archive.

gci {TargetDirectory} -file  | Copy-Item -Destination { "$([System.IO.Path]::GetRandomFileName()).{Target Extension}" } -whatif

  • This operation copies the file to the current directory.
  • The GetRandomFileName will generate both random text and random lettered extensions.

I needed my files to be all of the same type so I this is the format I used:

gci C:\Test\Initial -file  | Copy-Item -Destination { "$([System.IO.Path]::GetRandomFileName()).zip" } -whatif


Using Cisco AnyConnect In A Virtual Machine

Using Cisco AnyConnect In A Virtual Machine is Problematic. This post details how to enable that operation from within the virtual machine.


When one attempts to run the vpn in a virtual they are presented with:

Cisco Failure

The actual error is:

VPN establishment capability from a remote desktop is disabled. A VPN connection will not be established.VPN establishment capability from a remote desktop is disabled. A VPN connection will not be established.

Cisco Resolution (InComplete)

Cisco advises to resolve by changing the value WindowsVPNEstablishment to AllowRemoteUsers and references a now defunct web page.

How to enable Cisco Anyconnect VPN through Remote Desktop

Unfortunately it does not specify if that is on the server or client.

Resolution (Client)

To resolve the issue one has to intercept a downloaded file CHS-TwoFactor-VPN_client-profile.xml downloaded/modified during connection and change 1 or more settings in this file. This method was proposed by the post Bypassing Cisco AnyConnects profile settings by Joao. His method was to create a C# filewatcher which when the XML file changed, to replace it with a settings file that had WindowsVPNEstablishment as well as WindowsLogonEnforcement commented out. But I found that his code/methodology had a couple of problematic issues which could cause it to fail. Specifically the value of the key WindowsVPNEstablishment needs to be set to AllowRemoteUsers and not just commented out I document my solution below.

Xml Changes





Note that I do not change the WindowsLogonEnforcement as advised by Joao because I am surmising that I only have one connection to coporate at a time which is in the Virtual Machine. I believe that this setting is for multiple connections(?) … so if you run into further issues, that may need to be addressed.

C# Code

Design Considerations

  • C# program which can be compiled outside of Visual Studio by C:\Windows\Microsoft.NET\Framework64\v4.0.30319\csc.exe {filename}.cs
  • Deletes the existing initial XML file as first step. Requiring a new download by the CISCO process.
  • Watch the directory %ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile for changes.
  • When change of Created is thrown, delete downloaded file and replace with backup file in the same directory which has aformentioned xml changes ready to go.
class Program
    static string FileName => "CHS-TwoFactor-VPN_client-profile";
    static string Directory => @"C:\ProgramData\Cisco\Cisco AnyConnect Secure Mobility Client\Profile";
    static string PathedFileName => $@"{Directory}\{FileName}.xml";

    static bool HasReplaced = false;
    static void Main(string[] args)
        Console.WriteLine($"Watcher started on Directory{Environment.NewLine}{Directory}");


        var watcher = new FileSystemWatcher(Directory);
        watcher.EnableRaisingEvents = true;

        watcher.Created += Watcher_Changed;
        watcher.Changed += Watcher_Changed;
        watcher.Deleted += Watcher_Changed;

        while (!HasReplaced)

        watcher.Created -= Watcher_Changed;
        watcher.Changed -= Watcher_Changed;
        watcher.Deleted -= Watcher_Changed;

        watcher = null;

    private static void Watcher_Changed(object sender, FileSystemEventArgs e)
        if ((e.ChangeType == WatcherChangeTypes.Created) || (e.ChangeType == WatcherChangeTypes.Changed))
            switch (e.ChangeType)
                case WatcherChangeTypes.Created: Console.WriteLine("Created Event"); break;
                case WatcherChangeTypes.Changed: Console.WriteLine("Changed Event"); break;

    static void ReplaceFile()

        File.Copy($@"{Directory}\{FileName}.bak", $@"{Directory}\{FileName}.xml"); 

        HasReplaced = true;
        Console.WriteLine("File Replaced");

    static void DeleteFile()
        if (File.Exists(PathedFileName))
            Console.WriteLine($"Removing {FileName}.xml");


XML File

  1. In the %ProgramData%\Cisco\Cisco AnyConnect Secure Mobility Client\Profile create a backup file named CHS-TwoFactor-VPN_client-profile.bak with the changes mentione in the XML Changes section.

This is used by the C# program to replace the downloaded file from Cisco at the right moment.

C# File

  1. Copy the exe (only ignore other uneeded files) generated into a directory on the virtual machine.
  2. Create a shortcut on the desktop to the file. (in Explorer Drag exe file while holding CTRL-Shift to create a link).
  3. Right Click the Link on the desktop and Run as administrator.
  4. Login through AnyConnect.

Note that the program will show status and if you want to see that status, run the program from a command shell which is run as an administrator.


Verify All Multiple Downloaded Files’ Checksum In Powershell

I ran into this need while downloading the Oracle VirtualBox Image for its Developer Database which was 7ziped into 14 files. I wanted a way to view all the checksums using Windows 10 certutil program without having to type it into the command line. Here is the command used from the directory.:

     gci  | foreach { certutil -hashfile $_.fullname MD5 }

I had other files in the directory so I wanted to filter only on those files:

     gci -filter *.ova.7z.0** | foreach { certutil -hashfile $_.fullname MD5 }


Failures Misdiagnosed As Being Dock Related; Its the PC drivers that are out of date…..HP ZBook 150W Thunderbolt 3 Docking Station

This was originally submitted to Amazon as a review, which was rejected. Hence I will review it here. I do not get any monies from reviews; but felt that the reviews for the dock on amazon were all negatives and one should review it with the proper way to update the dock.

For HP ZBook 150W Thunderbolt 3 Docking Station 5 Stars.

I receive, from my work, this dock with an HP ZBook 15 G3. Out of the box I did not notice any issues and everything seemed to work fine (with no updates having received this on 9/2018).

But since I was using the laptop/dock with a 34 inch monitor I wanted to make sure the video drivers were up to date. So to update the individual components on the dock, I went to HP’s site and from the dock’s info page, I downloaded two update packages specific for this dock. (See picture of the finalization of the update where it checks individual components to verify if they need updates). Once I did that update the Ethernet port failed on the dock but worked on the machine. Reason being is that the Ethernet driver is held on the PC and not the dock. So the PC was not playing well with the dock; people have assumed its the other way around and given bad reviews.

What I discovered, in researching and reading from others who had the issue as reported on the HP forums was that the Ethernet port on the dock is different from the one on the laptop and needs a specific driver. While doing research to find the exact driver, I discovered that HP, like Dell, has an updater program called `HP Support Assistant. (Makes life soooo much easier to update machines these days with these programs).

I had the site load software which recognized my pc and downloaded the HP Support Assistant. Once installed it correctly determined the make/model and warranty status of the machine. (See pic 2).

Most importantly when one allows it to scan the PC it finds all the drivers which need updating, and updates them with minimal help from the end user.

Since it was a new laptop it had 16 items, the Ethernet port as one of them, which needed to be updated. After all those updates, all worked with the machine and the dock; and its Ethernet port.

Long story short is that other people had real problems, but were unable to update the device & PC so it can work properly. If you use the HP Support Assistant and keep fresh with the updates, at least as of this writing, all is great with this dock.

The only con I notice is that when switching virtual windows on my 34 inch monitor, it is not as fast as when I switch using a different computer with a dedicated graphics card.

I do not work for HP/Amazon or any company entity associated with the dock or PC.


Identify Invalid Azure Container Names Using .Net Regex

Not finding a satisfactory method to find invalid Azure Container names, I wrote my own easier (?) to read regex pattern for .Net.

^                       # Anchor; beginning of line. 
(?!.+--)                # String ahead does not contain two dashes 
(?!^-)                  # String ahead does not start with a dash 
(\$root|[a-z\d-]{3,63}) # Either literal root or a combination of lower case. 
$                       # Anchor; end of line


Using a negative look ahead convention (which does not match anything) to handle the double dash situation makes it easier to read.

The first rule says from the beginning of the line, there should not be two dashes or to start with a dash. Once valid, then either match the literal text “$root” or then match only lower case letters, numbers or a dash for a total of three characters to 63 characters.

Remember to run the above pattern with IgnorePatternWhiteSpace, which allows us to comment it. Or run without any option by specifying it on one line:


Here are the rules for Container names:

Valid naming for a Container in Azure Blob Storage.

1.  3 to 63 Characters

2.  Starts With Letter or Number

3.  Letters, Numbers, and Dash (-)

4.  Every Dash (-) Must Be Immediately Preceded and Followed by a Letter or Number

5.  All letters in a container name must be lowercase.


PowerShell: Kill VPN Related Processes And Launch IE to Companies Website

While working for a company which used a browser based VPN which needed to have different pinned components in memory. That caused difficulties when having to mostly re-login due to their startup script. I created this PowerShell script to kill specific processes, if running, and launch IE to my companies’ web page.

Get-Process | where {      
                     -or $_.Name -like "Juniper*"`__abENT__lt;code__abENT__gt;-or $___abENT__#95;__abENT__#95;abENT__abENT__#95;__abENT__#95;#46;Name -like __abENT__#95;__abENT__#95;abENT__abENT__#95;__abENT__#95;quot;dsHostChecker*__abENT__#95;__abENT__#95;abENT__abENT__#95;__abENT__#95;quot;__abENT__lt;__abENT__#8260;code__abENT__gt;`
                     -or $_.Name -like "iisexpress"`__abENT__lt;code__abENT__gt;-or $___abENT__#95;__abENT__#95;abENT__abENT__#95;__abENT__#95;#46;Name -like __abENT__#95;__abENT__#95;abENT__abENT__#95;__abENT__#95;quot;Network*__abENT__#95;__abENT__#95;abENT__abENT__#95;__abENT__#95;quot;__abENT__lt;__abENT__#8260;code__abENT__gt;`
                 -or $_.Name -like "dsNcService*"`__abENT__lt;code__abENT__gt;}__abENT__lt;__abENT__#8260;code__abENT__gt;`
            | Stop-Process -Verbose -Force

$ie = New-Object -com internetexplorer.application; 
$ie.visible = $true; 

If you have any failures try running this script with admin privileges on the box.


Entity Framework Stored Procedure Instructions

This is a how-to on getting Entity Framework (EF) version 5 and 6 to include stored procs and how to consume the resulting entities in code.

  1. In the EF designer choose `Update Model From Database`.
  2. When the page to `Choose Your Database Objects and Settings` comes up which allows one to add new tables/views/stored procs, select the stored proc of interest. Remember the name for the resulting data mapping entity will be the name with the extension `_Result`.2015-06-12_19-10-39
  3. Once the wizard is finished EF will contain the stored proc in the `Model Browser`. The model browser can be displayed by right clicking the EF design surface and selecting `Model Browser`.2015-06-12_19-51-20
  4. Here is an explanation of what has happened.
    (1) You have added the stored proc into the `Stored Procedures __abENT__#8260; Functions` as an item of interest.
    (2) EF has created a function import of the stored proc and placed it into `Function Imports`.
    (3) If EF was able to determine the *result set entity* it will most likely be in the `Complex Types` folder.
  5. If the mapping has gone right you should be able to call the stored proc off of the EF context in code and it will return a list of the complex type `xxx_Result`. If it works you will know it, but there could be problems with the mapping.

Mapping Problems and How to Resolve

  • One can delete at anytime the any object in the folders of 1/2 or 3 shown above and regenerate or create a custom mapping. Don’t be afraid to delete.
  • Sometimes very complex stored procs will not divulge the right mapping of the entity in the result set and the resulting complex type will cause failures. One way around that is to create a faux data return in the stored proc which leaves no ambiguity for Ef.
          1. In the database change the stored proc as follows.  Comment out the meat of the result select and replace it with a one-to-one column stub faux select such as this example: “SELECT 1 AS ResultId, ‘Power1’ AS GroupName, ‘Test’ AS Description”. Note to be clear you will need to match every column and name.
          2. In EF’s Model Browser delete all things associated with the stored proc in folders 1, 2 and 3 above.
          3. Regenerate all by using`Update Model From Database`.
          4. Check the results.
  • If the above steps fail one can always create a function mapping by hand. Be careful not to create duplicates, if so delete all and start over.
        • Open up and find the stored proc you inserted into folder #3 above. Right click and select`Add Function Import…`2015-06-12_20-09-09
        • One can get the column information, change items on the above screen; it is trial and error.
        • You will need to play around with this until you have the right columns for your function import. Be wary of numbered copiesof the complex types which may be created from the mapping.

Remember to reset the stored proc back to its original state instead of the faux stub mentioned.