in

vbCity Blogs

New (temp) place for vbCity Blogs

CanOz Blog

Neil Knobbe's place for Visual Basic.NET and WPF
  • Expander Control and Silverlight 3

     For a while now I knew that the WPF Expander control was going to be included for use with Silverlight 3. The official Silverlight site mentioned it more than once.

    I even found some blogs that showed using the Expander with Silverlight, but when the time came to insert an Expander into a new Silverlight project all the good feelings stopped.

    Error and assumption number 1:

    All the new Silverlight controls are not automatically included in the Visual Studio ToolBox.

    I am not sure why it was done this way but they are not.  I could see some of the new controls, like the TabControl, which I also wanted to use but not the Expander.  At the beginning this was not a big problem for me because I had other projects to work on that didn’t require the Expander, but when time came to start the project with it I was in trouble.  I asked a friend about it and he reminded me to try the “Choose ToolBox Items” option which can be found under “Tools” in the main menu of Visual Studio.

    Selecting the Silverlight Components tab on the new window I could choose from 40 Silverlight controls.  Everything I could want from a Border to a ToolTip.

    There was one problem however.  No Expander control.

    I was no further ahead so I did some more investigating.

    Error and assumption number 2:

    Don’t just because it is written doesn’t mean that the item in question won’t change after publication.

    Some things can change in software between builds and versions (beta, SDK, release, Silverlight 2, Silverlight 3 etc) and at some point in time I what I have written here there will be a good chance that I will be caught in the same trap.

    I spent a good amount of time on Google looking for examples of using the Expander control in a Silverlight application and found more than a few examples.  There was one common element which kept me banging my head against the wall.  Most, if not all, the examples showed adding the reference to the System.Windows.Controls library and adding the Namespace to the Silverlight UserControl.

    I had gotten that far as I was also using the TabControl on this particular project.

    <UserControl

       xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

       x:Class="Expander.Page"

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       Width="400" Height="300">

     To get access to the Controls in the Namespace I would just type "basics:" in the XAML for the UserControl and Intellisense would show me the Controls available to me.

    Yet again there was no Expander available to me.  I was pretty sure that the Expander was useable with Silverlight 3 as there is Sample Source Code in the Silverlight 3 SDK so it followed, in my mind at least, that it should be accessible in Visual Studio.

    Solution:

    The solution to this was in one way good to get yet in another it brought another minor annoyance with it.

    I re-read what this page on the Silverlight Toolkit on the CodePlex site and noticed a minor but important fact.  The Expander control is not actually in the same Library as the TabControl like I thought when I first read the page.  The TabControl is in the System.Windows.Contols library.  The Expander is in the System.Windows.Controls.Toolkit library.  I missed the “Toolkit” part and quickly realized that I would have to add another reference to the project.

    To add the Reference, I right clicked on References in the Solution Explorer window of the project and from the sub-menu selected “Add Reference”.  From there I clicked the “Browse” button and navigated to the Silverlight SDK directory and dug down in the sub-directories until I found the System.Windows.Controls.Toolkit.dll file, selected the file and added by clicking the “OK” button.

    The next step was to add the Namespace to my project.  There is time when Intellisense is really your friend.
    I started with xmlns:controls= and was presented with a choice to select from.

    Double clicking on the System.Windows.Controls.Toolkit option got Visual Studio to complete the declaration for me and I was ready to use the Expander.

    <UserControl

       xmlns:basics="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls"

       xmlns:controls="clr-namespace:System.Windows.Controls;assembly=System.Windows.Controls.Toolkit"

       x:Class="Expander.Page"

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       Width="400" Height="300">

     You would think after all this and getting the Expander into my project that I would finish with a really happy ending but I can’t say that I am 100% satisfied.

    There is still one thing that bothers me but because I now have access to the Expander control I can live with it. 

    The bother?  When I type in the XAML markup for an Expander Intellisense does not show what controls are included in the Toolkit library like the Windows.Controls library does in the image above.

    I did find it rather interesting that it does pick up all the Properties of the Expander once I have typed in what control I am trying to use.

    Like I said it is a small bother but one that I can live with.  At least I have use of control I really want in my project.

  • Extra ScrollBars with Silverlight 3

    This was a rather interesting one that I only stumbled upon.

    Now that Silverlight 3 has been released, I figured it was time to update some web sites that I look after and get away from the plain HTML with CSS that I had been using.

    It took much less time that I thought to get the first site set out and running the way I wanted or so I thought.

    Most of the site content was put into a ScrollViewer as I knew it would extend past the bottom of the window and someone viewing the site would be required to scroll at some point in time.

    I developed the site on my laptop and it all through development and deployment it looked fine, but when I happened to take a look at the site on my desktop machine I noticed that there were two ScrollBars showing on the Internet Explorer window.

    This was a mystery to me as I knew that there were not two ScrollBars when I was developing the site.

    After a giving this problem some serious though for a while I realized what the problem may be.  Normally I keep both machines the same but currently my laptop and desktop were different in one aspect.

    Internet Explorer.

    My laptop was running Vista with Internet Explorer 7 and my desktop was running Vista with Internet Explorer 8.  At least now I knew where the problem lay.  Not how to fix the problem mind you, just why I was seeing what I was.

    As it turns out the fix is quite simple.

    When Visual Studio creates a Silverlight application, and the accompanying web site that can host the Silverlight application, it adds some CSS Style for the page.

    <head>

        <title>SilverlightApplication4</title>

     

        <style type="text/css">

        html, body {

            height: 100%;

            overflow: auto;

        }

        body {

            padding: 0;

            margin: 0;

        }

        #silverlightControlHost {

            height: 100%;

        }

        </style>

     In the HTML above it is the value of the overflow property that determines if the ScrollBar for the window is displayed or not.

    IE8 is just different enough from IE7 that setting the overflow to auto generates the extra ScrollBar.  I suppose a better way to say it is that it does not let the ScrollBar from the Silverlight application replace the ScrollBar of the IE window like it does in previous versions.

    To get around this problem, you need to change the overflow setting from “auto” to “hidden”.

    <head>

        <title>SilverlightApplication4</title>

     

        <style type="text/css">

        html, body {

            height: 100%;

            overflow: hidden;

        }

        body {

            padding: 0;

            margin: 0;

        }

        #silverlightControlHost {

            height: 100%;

        }

        </style>

     Once overflow is set to hidden, IE will open without a ScrollBar which leaves the person viewing the site with the ScrollBar of the Silverlight application to use instead.

    These are the kinds of problems that I like.  Nice and easy to fix.

  • Blending Images

    Recently I have been updating, or rather upgrading may be a better word, a few web sites that I have been looking after for years.

    I have been using some Javascript to blend images in a sort of slide show and decided that if I was going to change the web sites over to Silverlight 3.0 that it was as good as time as any to replace the decade old Javascript as well.

    I would like to say that I am so well versed in XAML that all I had to do was manually type in the required XAML to the Silverlight project that I started in Visual Studio, but alas such is not the case so I had to use the very handy Expression Blend as the tool to create the effect I wanted for the images.

    The effect I was after was to have a set of five images that would be displayed one at a time then after a set time dissolve to display the next image in an endless loop.

    To accomplish this I knew that I would need to create a Storyboard and use DoubleAnnimationUsingKeyFrames to get the job done.

    I placed all five images in one cell of a Grid,

    setting the Height property of all the images to be the same as well as setting the Opacity of four of the images to 0 and the Opacity of the last to 1 so that only one image was visible at the start.
    So my starting XAML is:

    <Window

        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        x:Class="Window1"

        x:Name="Window"

        Title="Window1"

        Width="640" Height="480">

     

        <Grid x:Name="LayoutRoot">

            <Image Name="image1" Source="pics\jps6.jpg" Height="200" Opacity="1"/>

            <Image Name="image2" Source="pics\jps9.jpg" Height="200" Opacity="0"/>

            <Image Name="image3" Source="pics\jps11.jpg" Height="200" Opacity="0"/>

            <Image Name="image4" Source="pics\kids.jpg" Height="200" Opacity="0"/>

            <Image Name="image5" Source="pics\play7.jpg" Height="200" Opacity="0"/>

        </Grid>

    </Window>

     

    The next step was to create the Storyboard.  To create a Storyboard you need to click the New button located on the Objects and Timelines panel.

    After clicking the New button you are prompted to either accept the default name for the Storyboard or enter your own name for the Storyboard.  For my example I have renamed the Storyboard “BlendingImages”.

    Once you have accepted the name for the Storyboard, Timeline recording is turned on and a Storyline is added to the Objects and Timeline panel.

    Next a KeyFrame for the Element to be changed, in my case the first image, needs to be added.  To add a KeyFrame you need to do two things.

    1)  In the Objects and Timeline panel select the Element you want to add the KeyFrame for. (Number 1 in the image below.)

    2)  Click on the Record KeyFrame Button above the Timeline. (Number 2 in the image below.)

    A KeyFrame will then be added to the Timeline of the Element that has been selected. (Number 3 in the image below.)

    Now that the KeyFrame has been added the Properties for the Element can be changed to what I want in the Properties Panel of the Element.  In my case I don’t actually want to make any changes to the Element just yet.

    The effect that I am going for is to have the image show for six seconds then fade away over the next three seconds.  When the image that is showing starts to fade, I want the next image to start to appear over the same three seconds that the current image is fading.

    Adding a second KeyFrame is the same as adding the first one.  Move the Timeline but using the small ScrollBar under the actual Timeline until the six second line is visible then click the Record KeyFrame button again.  A second KeyFrame for the Element will be inserted on the timeline for the Element.

    The second image is selected and a KeyFrame is added to the Timeline for the second image.

    Once again I don’t want to make any changes to the Properties of either image, but if you wanted to all you need to do is select the Element and then set whatever Properties you want in the Properties panel for the Element.

    Another KeyFrame needs to be added for each image at nine seconds.

    Now I am ready to make some changes to the Properties of my two images.

    For the first image I set the Opacity to 0 which will make it invisible and the second image I set the Opacity to 100 so that is will now be seen.

    You will also notice that it shows in the Objects and Timeline panel that there has been changes to the Elements.

    One other point you may be curious about is why I added the KeyFrame to image1 at six seconds.  The reason for this is the change in an Elements Property is done over the entire time between KeyFrames.  As a result the image would be wholly visible for about half the time, four and a half seconds, before starting to fade prior to the second image started to appear which is not the effect I was after.  By adding the second KeyFrame at six seconds I ensured that the first image was still wholly visible at the time the second image started to fade in.

    You can click on the Play button in the Objects and Timeline panel to test the Effect to make sure that it is working the way you want.

    The starting animation worked so I set about adding KeyFrames and setting Properties for the rest of my images to complete the blending effect.

    I should mentions that since I wanted this effect to repeat, the last three second of the effect I set the original image to start to become visible again and the last image fade out.

    To get the effect to repeat you need to set the RepeatBehaviour property of the Storyboard.  You can do this by either adding the XAML yourself or by clicking once on the name of the Storyboard in the Objects and Timelines panel then selecting the value for the RepeatBehaviour.

    I wanted to effect to continually repeat so I set the property to Forever.

    Testing the effect showed it worked so I was able to now insert the XAML for the Storyboard into the Silverlight project in Visual Studio.

    Below is the complete XAML for the Storyboard.

            <Storyboard x:Key="BlendingImages" RepeatBehavior="Forever">

                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                              Storyboard.TargetName="image1"

                                              Storyboard.TargetProperty="(UIElement.Opacity)">

                    <SplineDoubleKeyFrame KeyTime="00:00:06" Value="1"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:09" Value="0"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:42" Value="0"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:45" Value="1"/>

                </DoubleAnimationUsingKeyFrames>

                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                              Storyboard.TargetName="image2"

                                              Storyboard.TargetProperty="(UIElement.Opacity)">

                    <SplineDoubleKeyFrame KeyTime="00:00:06" Value="0"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:09" Value="0.995"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:15" Value="0.995"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:18" Value="0"/>

                </DoubleAnimationUsingKeyFrames>

                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                              Storyboard.TargetName="image3"

                                              Storyboard.TargetProperty="(UIElement.Opacity)">

                    <SplineDoubleKeyFrame KeyTime="00:00:15" Value="0"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:18" Value="0.995"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:24" Value="0.995"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:27" Value="0"/>

                </DoubleAnimationUsingKeyFrames>

                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                              Storyboard.TargetName="image4"

                                              Storyboard.TargetProperty="(UIElement.Opacity)">

                    <SplineDoubleKeyFrame KeyTime="00:00:24" Value="0"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:27" Value="1"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:33" Value="1"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:36" Value="0"/>

                </DoubleAnimationUsingKeyFrames>

                <DoubleAnimationUsingKeyFrames BeginTime="00:00:00"

                                              Storyboard.TargetName="image5"

                                              Storyboard.TargetProperty="(UIElement.Opacity)">

                    <SplineDoubleKeyFrame KeyTime="00:00:33" Value="0"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:36" Value="1"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:42" Value="1"/>

                    <SplineDoubleKeyFrame KeyTime="00:00:45" Value="0"/>

                </DoubleAnimationUsingKeyFrames>

            </Storyboard>

     To get the effect running there was a couple of tweaks that were required in the Silverlight project.

    The first was I needed to give the UserControl a Name so that I could access the Events for the UserControl from the .vb code behind page.

    Opening the code behind page I went to the Loaded Event of the UserControl and added the code that would find the Storyboard as a Resource of the UserControl and start the effect when the page was loaded into the user browser.

    The code is relatively simple at three lines.

    The first line declares a Variable as a Storyboard.

    The second line sets the value of the Variable to be the Storyboard that I created in Blend and copied into my Silverlight project.

    The third line of code starts the Storyboard to begin the effect.

        Private Sub BlendingImages_Loaded(ByVal sender As Object, _

                                      ByVal e As System.Windows.RoutedEventArgs) _

                                      Handles BlendingImages.Loaded

     

            Dim MyStory As Storyboard

     

            MyStory = CType(Me.Resources("BlendingImages"), Storyboard)

     

            MyStory.Begin()

     

        End Sub

     Now I have the same effect, which can be seen here as I had before with a couple of benefits.

    The first benefit is that I am not limited to needing all the images to be exactly the same size and shape and the markup for the XAML Storyboard is less than the Javascript function.

  • WPF Pages and Custom Designed Hyperlinks

     It seems like Hyperlinks are my main focus this week.

    Once I had gotten the Hyperlinks with Images working for my current project, I got to thinking about my next project and just what I could get Hyperlinks to look like.  It turns out that you could do just about anything you want to create a Hyperlink.  The only thing limiting you is your imagination though you may want to temper your imagination and not make anything too gaudy.

    I had a vague idea of what I wanted and one thing I definitely wanted to do was use the existing colour scheme using Yellow and Teal.  Instead of two separate colours I decided I wanted to use a Gradient colour so the first thing I did was create a LinearGradientBrush as a Page Resource so I could easily re-use it throughout the project.

        <Page.Resources>

            <LinearGradientBrush x:Key="MyBrush"

                                StartPoint="0,0" EndPoint="1,1" Opacity=".75">

                <GradientStop Color="Yellow" Offset="0"></GradientStop>

                <GradientStop Color="Teal" Offset="1"></GradientStop>

            </LinearGradientBrush>

        </Page.Resources>

     I am going to make a small side trip here, but I feel it is an important one.  In this post, and my two previous, I mention that I am using a Windows Presentation Foundation (WPF) Page for my projects.  I also mentioned that the Users web browser, Internet Explorer 6 in this case, is going to be used to view the page.  (At the time of writing this post you can only use Internet Explorer 6 or higher to view a page with XMAL markup).

    Without a slight modification to a Page that is automatically generated by Visual Studio, and Expression Blend, the page itself will not open in the web browser.  There will be an error generated.

    When Visual Studio creates a WPF Page the XAML markup for the page looks like the following:

    <Page x:Class="Page1"

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       Title="Page1">

        <Grid>

     

        </Grid>

    </Page>

     which is fine if you are going to run your application in a WPF Navigation window.  If you, like I want, wish to display the page directly in Internet Explorer, then you must remove the reference to the Class name.  Your XAML for the base page would now look like:

    <Page

       xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

       xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

       Title="Page1">

        <Grid>

     

        </Grid>

    </Page>

    Now if you were to add some content to your page and try to open it with Internet Explorer the page would display assuming there are no errors in the page content XAML.

    With that small explanation out of the way it is back to the project.

    I wanted to have my Hyperlinks as an irregular shape, but not so irregular that I needed to create a Polygon shape for them.  What I was thinking of was something rectangular but with not all the corners squared.   The easiest way that I use for this is to use a Border.

    Knowing that I can’t use a Hyperlink without it being in an UIElement, I put a Hyperlink in a TextBlock and added the Border XAML between the opening and closing tags of the Hyperlink.

    I applied the LinearGradientColor I added as a page resource as the colour, or Brush, for the Border and set the Thickness of the Border to 10.  To give the Border a look of something other than a rectangle, I changed the top left and bottom right CornerRadius to 20 and 10 respectively.

            <TextBlock>

            <Hyperlink>

                <Border BorderBrush="{StaticResource MyBrush}"

                       BorderThickness="10" CornerRadius="20,0,10,0">

                </Border>

            </Hyperlink>

            </TextBlock>

    This gave me a starting point as can be seen in the following screenshot.

    Yes the Border is very small, but that is only because I have not put any content into it yet.  There is also that annoying little blue line showing it to be a Hyperlink too which I will deal with later.

    The Border can only hold one WPF Element, which will suit my purposes fine, but if you want to be more elaborate you will need to add a container such as the Grid before adding any other Elements.

    I am using a TextBlock to display the Caption of the link so between the opening and closing tags of the Border I inserted the XAML for the TextBlock.

            <TextBlock>

            <Hyperlink>

                <Border BorderBrush="{StaticResource MyBrush}"

                       BorderThickness="10" CornerRadius="20,0,10,0">

                    <TextBlock Background="{StaticResource MyBrush}"

                              Foreground="Teal" FontWeight="Bold">

                        vbCity.com</TextBlock>

                </Border>

            </Hyperlink>

            </TextBlock>

    I set three properties of the inner TextBlock, the Background to my LinearGradientBrush, the Foreground and FontWeight.  I set the FontWeight so that the Text of the TextBlock stands out a little more. 
    I now mostly had the look I was going for.

    I say mostly because I still had the blue line under the link showing it as a link which I didn’t want.  I also have not set the link itself.

    Setting the NavigateUri and TextDecorations properties of the Hyperlink fixes those two remaining issues.

            <TextBlock>

            <Hyperlink NavigateUri="http:\\www.vbcity.com" TextDecorations="None">

                <Border BorderBrush="{StaticResource MyBrush}"

                       BorderThickness="10" CornerRadius="20,0,10,0">

                    <TextBlock Background="{StaticResource MyBrush}"

                              Foreground="Teal" FontWeight="Bold">

                        Home</TextBlock>

                </Border>

            </Hyperlink>

            </TextBlock>

    The screenshot below shows the final look of the Hyperlinks.

  • Hyperlinks with Images and WPF Pages

     Continuing on the subject, and project, from my last post I will look at using an Image, as well as other WPF Elements, instead of plain boring Text as the visual for a Hyperlink on a WPF Page.

    The page in question will be viewed by the user in the web browser, in the instance of my application the browser will be IE6, which will link to external sites on the Internet.  We wanted to use the logo from the sites, sometimes with a caption under the logo, rather than just a textual link.

    It did take me a while to figure this one out mostly because that I forgot one of the really great things about Windows Presentation Foundation (WPF) which is that just about all WPF Controls, if not all, can hold any WPF object themselves which made setting up the Image links very easy.

    I started out with the Hyperlink itself.  Due to the fact a Hyperlink is not a UIElement I had to place the link itself in a TextBlock.

            <TextBlock>

            <Hyperlink NavigateUri="http:\\www.vbcity.com">

                Visit vbCity.com</Hyperlink>

            </TextBlock>

    The image below shows the link on the page.

    To get the image to be the Hyperlink, the XAML for the Image needs to be added between the opening and closing tags of the Hyperlink as well as removing the text of the link.

            <TextBlock>

            <Hyperlink NavigateUri="http:\\www.vbcity.com">

                <Image Source=".\vbcity_logo.jpg"></Image>

            </Hyperlink>

            </TextBlock>

     So I ended up with what I originally wanted an Image as a Hyperlink as the screenshot below shows.

    There was one other small nit-picky detail to take care of before I was finished.  If you look closely at the next screenshot, you can see a small blue line under the image indicating that the image is a link.

    I didn’t want the line under the image so I just had to set one more Property of the Hyperlink.  The property to be set is the TextDecorations Property of the Hyperlink to None.

            <TextBlock>

            <Hyperlink NavigateUri="http:\\www.vbcity.com"

                      TextDecorations="None">

                <Image Source=".\vbcity_logo.jpg"></Image>

            </Hyperlink>

            </TextBlock>

     Now you can see that there is no line under the link.

     

  • Hyperlinks and WPF Pages

    You may not think that this topic is worthy of a blog post, but I found the process interesting when the need for me to use Hyperlinks arose while working on a project.

    The project, I decided, was going to use a Windows Presentation Foundation (WPF) Page to give the User easy access to a listing of documents which reside on a shared drive.  The Page would be viewed through the Users web browser (in this case IE6) and then navigate to the document they wanted by clicking on the Hyperlink.

    Now you may be saying to yourself that this is a trivial task and, aside from design, all that was required was to add the link to the document in the NavigateUri Property of the Hyperlink.

            <!-- Absolute path of File -->

            <Hyperlink NavigateUri="file:///s:\directory1\directory2\file.doc">File 1</Hyperlink>

     

            <!-- Absolute path of Internet File -->

            <Hyperlink NavigateUri="http:\\www.neilknobbe.com">My Site</Hyperlink>

     

            <!-- Relative path of File -->

            <Hyperlink NavigateUri="file.doc">File 1</Hyperlink>

     

            <!-- Relative path of File in Sub-Directory -->

            <Hyperlink NavigateUri="subdirectory\file.doc">File 1</Hyperlink>

    Normally this would be the case, but due to the way that User Permissions were set up there was going to be two different possible Paths that the file could be found at depending on what permissions each user had.

    Most users, of the application, when they open the shared drive they are pointed to a directory which resides in a directory of the root directory on the drive.  Those with special privileges get directed to a directory one step up from the normal users.   Due to the possibility of different paths I could not use Absolute paths, like the first two Uri’s in the examples above, because I couldn’t determine which user was accessing the page.  This left me with using Relative paths for the files.

    Using Relative paths was fine to a degree if the files resided either in the same directory as the WPF Page or further down the directory tree of the directory the WPF Page was in.  In these cases I could use a path like the following.

            <!-- Relative path of File -->

            <Hyperlink NavigateUri="file.doc">File 1</Hyperlink>

     

            <!-- Relative path of File in Sub-Directory -->

            <Hyperlink NavigateUri="subdirectory\file.doc">File 1</Hyperlink>

    The majority of the files, in the case of my project, were in different directories than the WPF Page itself and as such using the previous type of Relative paths was not an option.  The WPF page was in a directory of the shared drive and all the other documents that I wanted to link to resided in their own topically named directories.

    What I needed to do was figure out how to navigate out of the WPF Page directory and into the other directories.

    In the end the answer was relatively, sorry no pun intended, simple.

    It turned out that to work up a directory tree for a Hyperlink you only need to add a full stop in front of the path for each directory up the directory tree you want to move up.

    Adding one full stop to the front of the Path sets the directory to be the directory that the Page resides in.  So I could also use the following for a file in the same directory as the Page.

            <!-- Relative path of File -->

            <Hyperlink NavigateUri=".\file.doc">File 1</Hyperlink>

    You could also use the same format for a file in a subdirectory.

            <!-- Relative path of File -->

            <Hyperlink NavigateUri=".\file.doc">File 1</Hyperlink>

    If, for example, I wanted to link to a file in a sibling directory of the directory the Page resides in then I needed to two full stops to the front of the Relative path of the file.

            <!-- Relative path of File in Sub-Directory -->

            <Hyperlink NavigateUri="..\siblingdirectory\file.doc">File 1</Hyperlink>

    As mentioned above, the first full stop sets the path to the directory that the Page resides in and each additional full stop moves one directory up the tree.

    In the case of my application the two full stops took the path up to what most users would see as the root directory of the shared drive, after that it was just a case of adding the sub-directory, or sub-directories, and the file name to complete the link.

  • Deploying A Silverlight 2 Application

    Either I am missing something or the information is just not out there in an obvious place.

    What I am talking about is deployment of Applications.  Windows, WPF, ASP.NET or Silverlight
    it all seems to be the same.  There is plenty of information about how to develop Applications but
    deployment seems to be a lacking topic.

    I was recently brought into a conversation about Silverlight 2 due to my interest in WPF and an
    application that I was developing for where I work.  The application is a WPF page that is run in
    the Users web browser and due to this it was suggested that Silverlight may be what I want to
    use to develop the application with.  As it turns out due to some limitations, or perhaps a better
    reason would be my lack of knowledge, that using Silverlight is not an option for my application
    but I am digressing from the topic of this post a little.

    My first look at Silverlight was with Silverlight 1.0 as I didn’t have 2.0 downloaded and installed at the time.

    There was nothing amazing about the project, just a red rectangle on a page as the whole object
    of my looking at Silverlight was to see about what files needed to be uploaded to the web server
    so the application could run.  The project consisted of 4 files.  One .html file, one .xaml files,
    one .xaml.js  file and one .js file.

    I uploaded the four files onto my server and the project ran as it should displaying my red rectangle.

    Deploying a Silverlight application seemed pretty easy.  In a way I was right and in a way I was wrong. 
    Deploying a Silverlight 1.0 application was easy, but that didn’t seem to be the case when I created
    my first Silverlight 2.0 application.

    I first knew I was in trouble when I created the application in Visual Studio 2008 and right off the bat
    I was given choices of how I wanted to set the application up.

    Not being sure what I wanted, and having worked a little with an ASP.NET web site before I chose
    that option from the Project Type dropdown box.

    My sense of foreboding got worse as I looked at the number of files that resided in the Solution
    Explorer window.  Xaml files, xaml.vb files, aspx files aspx.vb files, js files, config files I was
    beginning to wonder what I had gotten myself into and how I was going to get myself out.

    I pushed ahead and put an Ellipse, a Rectangle and a Button on my Page.xaml.

        1 <UserControl x:Class="SilverlightApplication3.Page"

        2    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        3    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        4    Width="400" Height="300">

        5     <Grid x:Name="LayoutRoot" Background="White">

        6         <Grid.ColumnDefinitions>

        7             <ColumnDefinition></ColumnDefinition>

        8             <ColumnDefinition></ColumnDefinition>

        9         </Grid.ColumnDefinitions>

       10         <Grid.RowDefinitions>

       11             <RowDefinition></RowDefinition>

       12             <RowDefinition></RowDefinition>

       13         </Grid.RowDefinitions>

       14         <Button Grid.Row="0" Grid.Column="0" Margin="20" Content="Change Colours"

       15                x:Name="Button1" Click="Button1_Click"></Button>

       16         <Ellipse Fill="Blue" Grid.Row="0" Grid.Column="1" Height="100" Width="150"

       17                 x:Name="Ellipse1"></Ellipse>

       18         <Rectangle Height="100" Width="150" Grid.Row="1" Grid.Column="0" Fill="Red"

       19                   x:Name="Rect1"></Rectangle>

       20     </Grid>

       21 </UserControl>

    In the code behind page I wired up the Click Event of the Button to swap the colours of the
    Ellipse and Rectangle as well as change the Content of the Button.

       10     Private Sub Button1_Click(ByVal sender As System.Object, _

       11                               ByVal e As System.Windows.RoutedEventArgs)

       12 

       13         Ellipse1.Fill = New SolidColorBrush(Color.FromArgb(254, 254, 0, 0))

       14         Rect1.Fill = New SolidColorBrush(Color.FromArgb(254, 0, 0, 254))

       15         Button1.Content = "Colour Changed!"

       16 

       17     End Sub

     Having read through Scott Guthrie’s Silverlight tutorials I knew that when the project
    was built there was a .xap file (pronounced “zap”) complied and placed in the ClientBin directory
    of the ASP.NET Web Site that would be hosting the Silverlight application.  Sure enough after
    building the project the .xap file appeared.

    I ran the project and sure enough when my web browser opened there was the Button,
    Ellipse and Rectangle all hosted nicely in the .aspx page.

    and when I clicked the Button, the colours of the shapes changed as well as the content
    of the Button as is it was supposed to.

    I was actually no closer to knowing what I needed to upload to my server, but at least
    I had a working application.

    One thing I did know was that I didn’t really want to have the application run as a ASP.NET
    web site on the server and I figured that it had to be able to be run from the .html page or
    there would be no reason for the .html page to be created when the project was created.

    To test my theory on this I navigated to where the .html page resided on the hard drive and
    double clicked on it.  The controls were there when it opened and the application worked like it
    should so I knew for a certainty that I didn’t need to have the web site configured as an ASP.NET
    web site.

    I went back and re-read Scott Guthrie’s tutorial about the .xap file being hosted within the web
    page which got me to thinking that the only files I needed to upload were the .html file and the
    ClientBin directory and the .xap file that resides in it.

    I uploaded the files to my web server, typed in the address of the .html page and ran smack into
    an error.  The application would not run.

    The error as it turned out was not because of my uploading the wrong files rather it turned out
    that I didn’t have the correct MIME type added to the site which was a new one to me.

    In order to get a Silverlight application to run on a web site you need to add the correct MIME
    type and extension.

    The MIME type and Extension are:

    MIME type: application/x-silverlight-app
    Extension : .xap

    Once you have this added to your site, the Silverlight application will run just like it does on the
    development machine.

    The link in the images is live and you can visit it to see the application in action.

    So the short answer to the question "What files do you need to upload to get a Silverlight
    application to work on the Internet if you want to host your application in a .html page?"

    Files:

    .html host page
    ClientBin directory and the .xap file that resides in it.

    The following MIME Type and Extension must be added to your server:

    MIME type: application/x-silverlight-app
    Extension : .xap

  • TabControl with WPF and Visual Basic.NET 2008 Project

    TabControl with WPF and Visual Basic.NET 2008 Project

    Sometimes it just takes me a while, but I finally got to the point where I figured I should also be including the Visual Basic projects to go along with the posts and the videos.

    You can download the project that goes along with the TabControl with WPF and Visual Basic.NET 2008 post.

    The project can be downloaded from here.

    My apologies for the size of the file.  It is a little bloated because of having the video file.

  • TabControl with WPF and Visual Basic.NET 2008

    TabControl with WPF and Visual Basic.NET 2008

    A while back I posted up about showing more interesting content on that tab
    of a tab control using Windows Presentation Foundation (WPF).

    In the example that I posted, I created the custom look of the tab control just using
    XAML and I thought that it would be good to also show how to do the same thing
    using Visual Basic.

    To do this I decided to cut back to the basics for the content of the tabs and I started
    with a tab control with four tabs.  The first tab had a textblock with some text as well
    as a couple style blocks in it.  The second tab starts with a stack panel.  The third
    and fourth tabs have grids on them.

    The XAML for my base project is.

        1 <Window x:Class="Window1"

        2  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"

        3  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        4  x:Name="Window1"    Title="Window1" Height="437"
           Width
    ="532" WindowStartupLocation="CenterScreen">

        5  <Grid x:Name="Form1">

        6     <TabControl>

        7         <TabItem x:Name="Tab1">

        8             <TabItem.Header>

        9                 <TextBlock x:Name="Tab1TextBlock">

       10                     <Span x:Name="Tab1TbSpan1">Words</Span>

       11                     <Span x:Name="Tab1TbSpan2">in</Span>

       12                     <Span x:Name="Tab1TbSpan3">Italics</Span>

       13                 </TextBlock>

       14             </TabItem.Header>

       15         </TabItem>

       16         <TabItem x:Name="Tab2">

       17             <TabItem.Header>

       18                 <StackPanel x:Name="Stack" Orientation="Horizontal">

       19 

       20                 </StackPanel>

       21             </TabItem.Header>

       22         </TabItem>

       23         <TabItem x:Name="Tab3">

       24             <TabItem.Header>

       25                 <Grid x:Name="Grid1">

       26 

       27                 </Grid>

       28             </TabItem.Header>

       29         </TabItem>

       30         <TabItem>

       31             <TabItem.Header>

       32                 <Grid x:Name="Grid2">

       33 

       34                 </Grid>

       35             </TabItem.Header>

       36         </TabItem>

       37     </TabControl>

       38  </Grid>

       39 </Window>

     

    The window does not look too interesting yet,

    but we will make it look better soon.

    Tab 1

    Within the XAML of the text block that is in the first tab, I have added in where
    I want the different styles to be.  I have giving the each span block a name so
    that it can be referenced by the code behind.

    There are different ways to go about this depending on what you want to do. 
    As you will see I have created one style with several different properties, since
    I am only going to be setting one property per span block I have only created
    one new style, or you can create a new style for each span block if you are
    going to have different styles for overlapping properties.

    I started off by declaring a variable as a New Span, then I set the properties
    for the variable that I wanted.

        1 Dim s As New Span

        2 

        3 s.Foreground = Brushes.Blue

        4 s.FontWeight = FontWeights.Bold

        5 s.FontStyle = FontStyles.Italic

    Now that I have the properties set, I just need to assign them to the various
    spans that I have on my tab.

        8 Tab1TbSpan1.Foreground = s.Foreground

        9 Tab1TbSpan2.FontWeight = s.FontWeight

       10 Tab1TbSpan3.FontStyle = s.FontStyle

     

    Tab one now has something more elaborate on it.

    Admittedly, I could have just used Brushes.Blue to set the Foreground of
    the first span, but by creating and using a new span I can now re-use this
    over and over in my code if I wanted to and if I wanted to change the
    colour, then I would only have to change one line of code rather than
    possibly having to several to change.

    Tab 2

    Tab 2 starts out with a stack panel on it with the orientation of the stack
    panel set to horizontal.I could have set the orientation of the stack panel
    with VB code if I wanted by using:

       12 With Stack

       13     .Orientation = Orientation.Horizontal

       14 End With

     

    if I wanted.

    In the stack panel I am going to place a text block, a rectangle and a circle.

    To add the text block, I need to start out with declaring a new text block
    then set the Text property.  With that done the last line of code adds the
    text block to the stack panel.

       16 With tb As New TextBlock

       17 

       18 tb.Text = "Circles and Rectangles"

       19 

       20 Stack.Children.Add(tb)

     

    I now have a caption on the second tab.

    Next I want to have a circle showing on the tab, so I declare a variable to
    hold a new ellipse and then set the Height, Width, and Fill.  I also set the
    Margin for the ellipse to a new thickness and pass the numeric
    representations of left, top, right and bottom to position the ellipse on
    the tab.  Once I have the properties I want set, I add the ellipse to the
    stack panel.

       23 Dim c As New Ellipse

       24 

       25 c.Height = 20

       26 c.Width = 20

       27 c.Fill = Brushes.Blue

       28 c.Margin = New Thickness(10, 0, 0, 0)

       29 

       30 Stack.Children.Add(c)

     

    Tab 2 now has a caption and a circle on it.

    The last item I wanted on the tab was a rectangle, so I did much the same
    for this as for adding the ellipse.  I declared a variable to hold a new
    rectangle then set the Height, Width and Fill.  Again I set the margin
    property to a new thickness to position the rectangle on the tab.  Then I
    added the rectangle to the stack panel.

       32 Dim r As New Rectangle

       33 

       34 r.Height = 15

       35 r.Width = 25

       36 r.Fill = Brushes.Red

       37 r.Margin = New Thickness(10, 0, 0, 0)

       38 

       39 Stack.Children.Add(r)

     

    I now have my desired look for the second tab.

    Tab 3

    Tab 3 will hold an image.

    Once again I start off by declaring a variable which will hold a new image,
    then set the Width and Source properties.The source property is declared
    as a New BitmapImage and the path of the image file, as well as what
    kind of Uri the path is, are passed as parameters of the Uri of the file. 
    The image control is then added to the grid on the tab.

       41 Dim v As New Image

       42 

       43 v.Width = 80

       44 v.Source = New BitmapImage(New Uri("Lizard004_RJ.JPG", _
                                     UriKind.Relative))

       45 

       46 Grid1.Children.Add(v)

     

    The third tab now displays an image.

    Tab 4

    The last tab on my tab control is going to display a video.

    I start out by declaring a variable to hold a new instance of a media element,
    then set the Width and Source properties of the element before adding the
    control to the grid on the fourth tab.

       48 Dim m As New MediaElement

       49 

       50 m.Width = 80

       51 m.Source = New Uri("butterfly.wmv", UriKind.Relative)

       52 

       53 Grid2.Children.Add(m)

     

    The tab now displays the video and completes the effect I was after.

    So you can see that it can be just as easy to do in Visual Basic what you
    can with XAML.

  • Video for Gadget Window

    Video for Gadget Window

    I have finished the video showing the process for creating a Gadget Style window.

    You can download it from here.

     

  • Multi-Line commenting

    Multi-Line commenting

    There are times when I have to wonder if I am the only person who does not know
    some things.

    I ran into this self doubt again the other day when I was watching one of Ron Cundiff's
    VB.NET Soup To Nuts WebCasts.

    During the WebCast one of the participants asked if there was a way to comment multiple
    lines of code.  When I heard this my ears perked up and I got very interested.

    In the, almost, ten years that I have been writing code, I always have commented out any
    lines of code I didn't want to run one line at a time.  What a time consuming effort that can
    be depending on the number of lines you are working with.  I also ended up with unformatted
    (not indented) code,

    and usually put the comment apostrophe in the wrong place when an indented line of code
    moved once the one above had been commented out.

    Well this is all changed now.  Low and behold there are buttons in the Visual Studio IDE that
    let you comment out, or uncomment, any lines of code that you have selected.  All this time
    I had a simple way literally staring me in the face.

    Right in the main Toolbar there is the Comment Button

    and the Uncomment Button.

    Now all I need to do to comment, or uncomment, multiple lines is highlight the code I
    want and click a button.

    One other great thing about this feature is that the code stays formatted (indented) even
    after commenting which, I believe, makes it much easier to read.

    *sigh*  Now I only have to wonder what other time saving “wonders” I will have to wait
    ten years to discover.

  • ClickOnce Deployment – Deploying files with your application

    ClickOnce Deployment – Deploying files with your application

    In a previous post, I showed you how you can deploy your application using ClickOnce. 
    Looking at how to deploy extra files, like my first look at ClickOnce, was prompted by a
    post on vbCity.

    Now I will admit that I wasn’t as sharp answering the original question as I could have
    been so be gentle with your opinion of me if you read through the thread.  (In fact it
    took me two days to work out that when the person asking mentioned the "Publish" tab
    that they meant ClickOnce.  I guess this is what I get for trying to answer questions a 3:30am.)

    Once I was in synch with the problem a little research provided me with an answer.

    You would have thought that once you added the files to your project in Visual Studio
    that they would be automatically included in the deployment package but this is not the
    case.  I added the file to my project,

    but if you were to then take a look at the files that are included in the deployment
    package by going to the Publish tab of your projects properties page and click the
    "Application Files" button you get a nasty little shock.

    No additional file even though we have added it to the project.

    The reason for this is that we have not told Visual Studio what we want to do with
    the file.  What is needed is to make one change to the properties of the file.  The
    property we want to change is the Build property.

    By default, depending on the extension of the file, when you add a file to a Visual
    Studio project the Build property is set to "None".

    (If you were using a deployment method like creating a Windows Installer file (.msi)
    then this would not be a problem because of the was you create the Installer file. 
    With ClickOnce deployment unless you change the Build property it assumes that
    you don’t want to include the file in the deployment package.)

    In the properties window of the file select “Content” from the choices for the files
    Build property.

    Now ClickOnce will recognize that the file is to be deployed with your application and
    if you go back to the My Properties page of your app, click on the "Publish" tab and
    click on the "Application Files" button you will see that the file in the list of files to be
    included.

    Publish your application, then you can do a test install and you will see by looking at
    the files that are installed on your computer now include the additional files.

  • ClickOnce increments

    ClickOnce increments

    Rockford Lhotka posted up some details about how ClickOnce handles what is downloaded
    when it performs an incremental update. 

    The more I look at ClickOnce the more I am coming to appreciate it.

    I know this goes against the ClickOnce idea, but if the end user could only determine
    where the Application is installed.  I suppose if I want to be that fussy I would just distribute
    and install via a Windows Installer file.

  • Deploying applications with ClickOnce

    Deploying applications with ClickOnce

    ClickOnce Deployment

    A recent post on vbCity regarding deploying an application with ClickOnce got me
    wondering about doing deployment with ClickOnce.

    I have always done deployment of applications by creating and using a Setup and
    Deployment package which created a .msi installer file, so it was interesting to
    see some of the differences between the two distribution methods.

    First off I created a simple application to test the ClickOnce distribution and
    installation method with.  What I created was nothing special, just a windows form
    with at button that, when it is clicked, a message box is shown.

     

    As you can see the application is nothing special.  One other thing that I did was
    add a version number to the text of the form.  I did this to show how ClickOnce
    deployment installs newer versions as they are available.  I will get to this a little
    later.

    Once your application is ready to go you want to open up the My Project page
    from the solution explorer.

    On the My Project  page click the Publish tab.

    From this page, you define where your application is going to be available from
    and how it is going to be installed on the client machine.

    Taking a look at the publish page from the top down the first thing you will want
    to enter will be the location (URL) that you are going to publish to.

    As you can see from the image above, you have three options for the location
    that you are going to publish to.  You can publish to a web site
    (http://www.somesite.com) but to do this you must have FrontPage extensions
    enabled on the web site.  You can publish to a ftp server (ftp://www.somesite.com)
    as long as you have ftp permissions for the site, or you can publish to a local file
    (C:\myApplication). (For distribution this last option is not really that realistic
    unless you are on an internal network where you can share out the directory to
    others on the network.)

    The next option you have is to determine if you application is available offline or not.

    If you don’t want the users to be able to access your application offline then
    select the online option.  This will cause your application to run, but not show in
    the start menu of the user’s computer.  They would need to download the
    application each time they wanted to use your application. 

    If you make the application available offline then a shortcut is included in the
    start menu of the computer making the application accessible all the time.

    To the right of the Install settings there is a group of four buttons.

    These buttons define what files are to be included with your application, any
    prerequisites that the end user must have installed on their computer to run
    your application, how and when to get updates as well as options such as
    adding the publishers name, product name etc.

    Under the install mode and the buttons there is the version boxes plus the
    option to automatically increment the revision with each publish.

    Keeping the increment box checked is, I believe, quite important.  If you don’t
    remember to increment the version number when you republish the
    application then the next time the application checks for updates it looks at
    the version number and if that number has not changed, even though your
    application may have, it assumes that there is nothing newer and opens the
    currently installed version.

    The last two items on the window are the Publish Wizard and Publish Now
    buttons.

    The Publish Wizard button will open a series of dialogues and walk you
    through the settings that you want your installer to use.

    The Publish Now button will use the information that you have entered
    on the page and create the installer files then, if you are deploying the
    files to either a web site or ftp site, prompt you for log on details.

    Simply insert your username and password then click the OK button and the
    files required will be uploaded to the URL you specified.

    You can see in the image above that ClickOnce has created two files and one
    directory on the web server.  Within the Application Files directory you would
    find one directory containing each version that has been published and uploaded.

    I just happen to have two versions in the application files directory and the one
    that will get distributed will always be the latest version. (I mentioned earlier that
    I had put a version number on the text of the form and the version number you
    should see is 2 not 1 like the image of the form above.) It would not matter how
    many older versions I have on my server.

    Now you may distribute the address of your application to your clients.  The file
    that you want to point to is the Application Manifest file, not the setup file. 
    From the image above I would point people to the URL
    http://www.neilknobbe.com/clickonce/ClickOnce.application.  (The link is live
    and you can navigate to it, download and install the application that I
    mentioned at the start of this post.  It is not very exciting, but it shows how
    ClickOnce works.)

    The prerequisites for installation, which you would have set earlier, are checked.

    If all is ok, the user will be prompted to install the application.

    Once installed your ClickOnce deployed application is ready to use.

     

  • Text and Image for Button with Visual Studio 2005

    Text and Image for Button with Visual Studio 2005

    Ok, let’s call this page 22,492 in the book of things I did not know about
    Visual Studio 2005.

    I was reading something the other day, if I can remember or find it I will post up a link,
    and was surprised that I had missed this little bit before. 

    (I have recently been reading “WPF for those who know Windows Forms” that can be
    found here  and watching webcasts by William Steele on his WPF Soup To Nuts series
    so it could have could have come from one of those.)

    What was mentioned was having both text and an image on a button.  I knew it was
    possible, but I didn’t know just how easy it was to do.

    By default when you add an image to the button the text of the button is overlays the image.

    There is a property of a button which helps us set the relation of the text to the
    image.  This name of this property is TextImageRelation.


    The TextImageRelation property has five options:

     

    • Overlay
    • Image over text
    • Text over image
    • Image before text
    • Text before image

     

    The options are pretty much self explanatory.  Below are screen shots showing
    the different positions.

    Image over text:

    Text over image:

    Image before text:

    and lastly

    Text before image:

     

More Posts Next page »
Copyright 1998-2009 vbCity.com LLC
Powered by Community Server (Non-Commercial Edition), by Telligent Systems