XTab's Blog

Ged Mead's Blog at vbCity

This blog hosted by:
http://blogs.vbcity.com      
  Home :: Syndication  :: Login

AprMay 2008Jun
SMTWTFS
27282930123
45678910
11121314151617
18192021222324
25262728293031
1234567

Archives

Topics

Ramblings

VB.NET

Wednesday, May 07, 2008 #

  One of the great things about WPF is its ability to let you use animation to enhance your user interface. (Or wreck it if you go too far!) In my opinion, subtle animations can go a long way towards improving the user experience.

  One particular way is to fade colors in and out so that text seems to appear and disappear in a way that gives the impression of movement, but without any jarring visual effects.

  Doing this in the XAML markup is well documented and you will find many examples around the place. However, I recently had a situation where I wanted to create this animation in the VB code behind. Now, I knew that anything that could be done in XAML can be done in VB, but when it came down to the task it actually caused me more problems than I'd expected. And when I started to search for answers, it took a while.

  It turned out that the reason for my difficulty was a fundamental misunderstanding on my part. I was thinking "color" as being the element to change or animate; in reality it doesn't work quite like that. But after a good deal of trial and error, I eventually hit on the answer.

   In this case I wanted to fade the text on a button from its original black to white. But because I would use this effect in a number of situations, including some where there was no user driven event to fire it, I decided that putting the animation instructions in the code behind was the way to go.

  I'll start with the XAML though, as I think that in most cases this will be your preferred route. I'll cover the VB approach at the end.

  here's the XAML:

Code Copy

<
Button Margin="30,67,0,111" Name="Button1" Foreground="Black" HorizontalAlignment="Left">Animated Button</Button>
  <Button
HorizontalAlignment="Right" Margin="0,77,96,111" Name="Button2" Click="Button2_Click" Content="Animated Button" >
    <
Button.Triggers>
      <
EventTrigger RoutedEvent="Button.Click">
        <
BeginStoryboard>
          <
Storyboard TargetProperty="Foreground.Color">
            <
ColorAnimation To="White" Duration="0:0:2" />
         </
Storyboard>
      </
BeginStoryboard>
    </
EventTrigger>
  </
Button.Triggers>
</
Button>

  Most of it is pretty straightforward:


1.  Having first created the button and set its main visual properties, we create a Triggers block for the Button.


2.  Next we identify the trigger to be used to fire this animation. In this case it is the Button's Click event.

3.  The Storyboard is then created and we identify the Target Property which is the Foreground Color of the button.

4.   Finally, the animation details which comprise the starting color, the ending color and the duration in seconds.

  The remainder of that code snippet are closing tags.

  Now it's the fact that the TargetProperty is identified as the Foreground.Color that threw me off the track when I came to create a VB version of this task. I was trying to find a way of assigning the animation directly to the Foreground Color of the button (or the Button.Content Color or various other permutations - none of which worked).

  The reason is that you have to set the animation on a Brush, and not directly to the Foreground property. You then assign this brush as the one to be used for the Foreground. And finally, when you run the animation to change the color of the brush, the animation is then seen to be applied to the Foreground. I hope that makes sense!

  Here's the VB code that does this:

Code Copy
' Create color animation sequence.
Dim
blackToWhite As ColorAnimation = New ColorAnimation(Colors.White, New Duration(New TimeSpan(0, 0, 2)))

'Create a new brush and apply the color animation to the brush

Dim
scb As SolidColorBrush = New SolidColorBrush(Colors.Black)

scb.BeginAnimation(SolidColorBrush.ColorProperty, blackToWhite)

'Assign the brush to Button's Foreground

Button1.Foreground = scb


  Like all these little glitches and gotchas, you wonder how it seemed so difficult once you've seen the answer. But as we all know, it's really easy to set yourself off on the wrong mindset and find yourself needlessly chasing your tail trying to get the exact syntax for what you're trying to achieve. Hopefully if you need to run this kind of animation in code, you'll now be saved a bit of potential frustration.

posted @ 9:03 PM | Feedback (0)

Tuesday, April 08, 2008 #

Introduction
  Printing can often be a bit of a tricky task in .NET. Some things are more easily resolved than others though.

  I saw a post recently that raised a problem that seems to occur fairly regularly: You want to print a large chunk of text to the printer, but VB seems to want to print everything all on one long line - even when this means that a lot of the text will be truncated or "printed" invisibly into thin air!

  Fortunately, this is one of the cases where the solution is relatively easy. Essentially, what you do is set a rectangle whose width represents the width of your printed page (or any lesser width you prefer). You then pass this rectangle to the DrawString method and it will obediently print within those boundaries.

Solution
   Here's the basic solution:

Code Copy
  Imports System.Drawing.Printing

Public
Class frmPrint

    ' The document you will use to print on
    Dim DocPrint As PrintDocument

   ' Set font for printing
        Dim fnt As Font = New Font("Verdana", 12, FontStyle.Regular)

'  The printing is fired with a button click event
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        '  Print the textbox content

        DocPrint = New PrintDocument
        ' A handler for it
        AddHandler DocPrint.PrintPage, AddressOf PrintTheTextBox1

        ' Print the document
        DocPrint.Print()
    End Sub

  '  The procedure that does the printing
  Private Sub PrintTheTextBox1(ByVal sender As Object, ByVal e As PrintPageEventArgs)

        'Set a rectangle to bound the  printing
        Dim PrintRect As New RectangleF
        PrintRect.Width = 800
        PrintRect.Height = 1000

        ' Print the text from the TextBox:
        e.Graphics.DrawString(TextBox1.Text, fnt, Brushes.Black, PrintRect)

    End Sub


 

Yes, But.....
  That's OK as far as it goes, but it does suffer from one flaw. When you check your printed page you'll find that the text is stuffed right up at the top left of the paper and each line extends fully across to the very last few millimetres at the right hand side. Now, it may be that paper saving is high on your agenda, in which case you'll be happy. But generally you will probably want a layout that's a bit more generous with its whitespace.

   The trouble is that there isn't an overload that allows you to pass in the Rectangle and the start position for the printing. Is that going to stump us? Nah, of course not!

  If we go back to the Rectangle itself, there is a constructor overload that allows you to pass in the x and y values as well as the width and height. The x and y values will of course be used as the left and top points respectively of the rectangle as it is positioned on the printed page. So this variation will get the start position, the text line width and text block height all sorted:

Code Copy
Private Sub PrintTheTextBox2(ByVal sender As Object, ByVal e As PrintPageEventArgs)

        'Set a rectangle to bound the  printing
        Dim PrintRect As New RectangleF(30, 100, 750, 1000)
       '  Assign its Left, Top, Width and Height values

        ' Print the text from the TextBox:
        e.Graphics.DrawString(TextBox1.Text, fnt, Brushes.Black, PrintRect)

    End Sub

  While I was working on that, I remembered that the Rectangle has a useful little method named Offset (something you would normally use when drawing actual rectangles in a graphics based task). However, by using this method and adjusting the values that are passed so that the top left of the rectangle is shunted down and to the right, we can get nearer to the layout we desire. If you chose to use this alternative route, it would look like this:

Code Copy
Dim PrintRect As New RectangleF
        PrintRect.Width = 800
        PrintRect.Height = 1000
        PrintRect.Offset(25, 60)

Show Me The Width
  It probably won't have escaped your notice that I very conveniently just happened to know what width and height I needed for the text to span across the page. Many times you will have this information to hand, but if you don't, what do you do then? Answer: You calculate it by querying the PrintDocument's PageSettings, find the width, height and margins and use those. Here's the code:

Code Copy
   Private Sub PrintTheTextBox3(ByVal sender As Object, ByVal e As PrintPageEventArgs)

        'Set a rectangle to bound the  printing
        Dim PrintRect As New RectangleF

        With DocPrint.DefaultPageSettings
            PrintRect.Width = .PaperSize.Width - (.Margins.Left + .Margins.Right)

            PrintRect.Height = .PaperSize.Height

            PrintRect.Offset(.Margins.Left, .Margins.Top)
        End With


        ' Print the text from the TextBox:
        e.Graphics.DrawString(TextBox1.Text, fnt, Brushes.Black, PrintRect)

    End Sub

Summary 

 Although there are many more tweaks we could add to this approach, I think that the above will cover many common situations. If text trimming at the end of lines is something you need to refine to the nth degree then you should check out the StringFormat class in general and the StringTrimming enumeration in particular. There are several options available there.

  Don't forget of course that you may not need to hand code your printing processes at all. There is a free Power Pack available which will print the contents of a form with minimum effort on your part. This will often be all that you need, but if not then at least you now know how to package up a bundle of text and send it to the printer to be laid out in a way that suits your requirements.

posted @ 5:06 PM | Feedback (0)

Sunday, April 06, 2008 #

  Friday was something of a Red Letter Day in the Mead household, because that was the day that the book I've been looking forward to getting for months finally arrived on my doorstep. At last - a WPF book aimed at those of us who prefer to use Visual Basic for the code behind. The book is Matthew MacDonald's "Pro WPF with VB 2008", published by Apress.

  In the couple of days since it arrived I obviously haven't been able to get too deeply into reading it - although my wife might offer a different opinion on how many hours I've spent with my head in this book since Friday! However, it's immediately clear that this is another well-written and comprehensive piece of work from a widely respected author.

  Unsurprisingly, large chunks of content have been ported directly from his earlier WPF book, which was based on .NET 3.0 and has C# as the code behind. This makes complete sense as it is only the code behind aspects that need the different approach. We VB-ers are just as able to understand the general WPF and XAML explanations as our allegedly "sharper" developer brethren.

  Because this is based on WPF 3.5 though, there are some additional items, such as binding to a LINQ expression in Chapter 16. There is also a completely new additional Chapter 26, which deals with the topics of Multithreading and Add-Ins.

  I don't think Apress have the full chapter listing on their site yet (or at least I couldn't see it if they did). However, rest assured that the whole gamut of WPF topics is covered in this book, from Layout to Dependency Properties, Routed Events to Navigation - in fact everything from Animation to Z-Index.

  The author has a very useful list of links that you can simply click on to save you (mis)typing them yourself from the book. These links and the downloadable code samples are available from here.

  In my opinion, you should buy this book for two reasons.

 First, it is an excellent, wide ranging, clear description of what you will need to know in order to get fully to grips with this exciting (but not always intuitive) technology.

  Second, there have been at least five WPF books published in the past year that have C# as the code behind. Publishers are in the business of selling books and they couldn't care less about whether C# or VB are "better". So I guess it's obvious that their stats show that they will sell more C# books. If you want to keep VB as a viable language, fully supported by authors and publishers, then the only way to ensure this is to make it worth their while to publish VB based books.

  So for either or both these reasons, I rate this book as one of the most worthwhile investments you can make if you are a VB developer (or student) and you want to fully embrace all the tempting offerings available in Windows Presentation Foundation.

posted @ 11:02 AM | Feedback (2)

Thursday, April 03, 2008 #

Developer Day Scotland

 

 

 The day of the first ever Developer Day Scotland is getting close!   Registration is still open and I hear that there are still a few places left.  

   So if you are anywhere in reach of Glasgow on Saturday 10th May 2008 and want to take advantage of this FREE event for developers, you can Register from this page.

  Wondering what's in it that might interest you?   Check out the agenda here.

  Colin and the guys have put in a huge amount of effort to get this off the ground, so I'm sure it will be a great day and well worthwhile attending.

  By the way, on a personal note, I'm hoping to use the event to assess if there is enough interest around to start a SouthWest Scotland (or even a SW Scotland and Cumbria) Section of Scottish Developers.   So if you live in this general catchment area and think you could be interested in joining such a group, please talk to me on the day.  And if you can't make the day and are still interested, contact me via this blog or email to xtab at vb(nospace)city dot com.

posted @ 8:14 AM | Feedback (0)

Sunday, March 09, 2008 #

  The latest .NET book from the Murach publishing house is "Murach's Visual Basic 2008". This book is essentially an update of their earlier book for VB 2005 which now includes additional coverage of new features such as Anonymous Types, Object Initializers and LINQ.

  I've just been re-reading my original review of the 2005 book and much of what I said then applies equally to this latest version. Here's what I said then:

  We all find that some particular authoring styles work better than others for us individually. Some of us like a mass of detail and repetition; some like a few terse lines of explanation. Some of us like to be jollied along with the occasional funny; some like to stay serious. Some like the pages to be jam-packed with screenshots and diagrams; others think this is a waste of teaching space.

  It's an individual thing.

  Murach have developed their own particular individual style. They use a "facing page" technique. Open the book up at any section and on the left hand page you will find a discussion or explanation of a topic. On the facing page you will see more specific information about this topic, possibly with a diagram or screenshots, or very often demonstration code samples.

  The benefit of this approach is that the author has two bites of the teaching cherry. She (in this case, author Anne Boehm) can introduce a topic on the left hand page, cover the essentials and be ready to move on. The value of the right hand facing page though is that it can be used to show additional detail, display sample code and example results and also (this I think being very important) can summarise the key points covered on the first page. The reinforcement of learning points in this way can be a very valuable tool.

  Essentially, the reader can decide if he or she has understood enough from the left side page to be ready to move on, or if not then they can opt to read the right hand page for more info, samples or reinforcement and confirmation of their understanding.

  Personally I quite like the approach. I tend to dive into books almost at random sometimes, but often just needing to refresh my memory on a particular point. If I'm using a Murach book and need further detail, I can dig into the additional facing page info as much as needed for any one topic, or even specific part of a topic.

  If there is a down side to the Murach approach it's probably that because of the facing pages approach they have to limit the number of VB.NET topics they can actually cover in the 800+ pages limit . That said, what they do cover is fairly comprehensive and contains plenty of material to keep a VB.NET beginner engrossed for many a long night. And, most importantly, those topics are covered thoroughly and clearly in plain English.

  A full list of the book Contents can be seen here and as you will see, you can drill further into each chapter to exactly what is covered.

  If you want to know if the Murach style will suit you, then you can take a look at two Sample Chapters here.

  In summary, this is another clearly written, well laid out offering from the Murach stable. This book is particularly suitable for newcomers to VB.NET, whether total developer beginners or those moving to .NET from VB Classic.

posted @ 3:07 PM | Feedback (1)

  I've been working in conjunction with Evan Lim and Young Joo to convert the source code examples from Charles Petzold into VB.NET. As at today there still doesn't seem to be a WPF book on the market that has  VB.NET as the code-behind (although I know there are a couple on the way). Add to this the fact that many C# to VB converters at the moment still get it wrong with several areas of the new Framework, this is a real stumbling block for many VB developers who would otherwise be much more interested in digging into WPF.

  The link to the final version of the conversion of Petzold samples is here. You can download individual chapter code or the whole shebang from the links in that blog item

  I've just started working on a similar project to convert the C# code of another WPF book. I'll post more once I've got something to show. In the meantime I hope that the Matthew McDonald and Billy Hollis WPF/VB books will be on the shelves before long.

posted @ 11:43 AM | Feedback (0)

Tuesday, February 19, 2008 #

  This is something that seems to come up fairly often in the Forums. Someone wants to test for a particular value in a ListBox and if the list does (or doesn't) contain the value then that item is to be deleted.

  One common way of doing this would be to use the Contains function to test if the target character or substring exists in the ListBox.

   This isn't a particular difficult task, but the thing that usually catches most beginners out here is that you have to traverse the ListBox items in reverse order. Well, you do if you actually end up deleting any items, anyway. The reason being that if you start from the top and work down, then as soon as you delete an item the ListBox's indices get out of sync and an ArgumentOutOfRange Exception will be thrown and you will get a message along the lines of the one shown below:

   In a recent post, a slight variation on this theme was that the check was to be made in one ListBox and if the required search string wasn't found in that first ListBox then not only was the item in the first ListBox to be deleted but also the corresponding item number in a second ListBox was also to be deleted.

  Again this is straightforward and the following code will do the job :

Code Copy
    Private Sub Button1_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles Button1.Click
        For i As Integer = ListBox1.Items.Count - 1 To 0 Step -1
            If Not ListBox1.Items(i).Contains(TextBox1.Text) Then
                ListBox1.Items.RemoveAt(i)
                ListBox2.Items.RemoveAt(i)
            End If
        Next
    End Sub

  As I say, it's not rocket science, but that traversing upwards trick is something worth knowing for these kind of situations.

posted @ 5:26 PM

Sunday, February 03, 2008 #

  I've had a copy of the excellent Camtasia Studio from TechSmith on my system for a while now and I've been itching to find time to create a video demo or two. 


   Just as everyone warned me it would be, it's a lot harder and takes wa-ay longer than you think it will, but my first effort is finally finished.

  As you can see from the blog heading, the video is a mini-tutorial on the subject of how to create a simple ControlTemplate in WPF.   The example I've used is a round button, just to show the techniques rather than try and get too fancy with the design.

    It's 99.9%  XAML; just one tiny bit of VB used to demonstrate that the templated button is wired up to the standard button Click event.

   The full-length video runs to just over 12 minutes and you can access it from HERE

or download a zipped copy HERE


  In addition, I was greatly encouraged by Karl Shifflett's clear and comprehensive article (not forgetting his demo videos!) on CodeProject  to try and create a Silverlight version too. In order to keep within the bandwidth limitations, I've had to break the original demo into two parts.

  You can view the same video streamed as a Silverlight application from the links below:


WPF ControlTemplate Part 1 Video

WPF ControlTemplate Part 2 Video

 

  If you want to view the Silverlight versions full screen, select the button shown in the image below for Full Screen and the Esc key to return to Default Size

 

posted @ 8:08 PM | Feedback (3)

Friday, February 01, 2008 #

  Quite often as I browse through the VB.NET Forums on vbCity I see questions about tasks that can be quite difficult in WinForms, but would be much easier to deal with using WPF. One recent question that fits this description is the following one:

"I am wondering how I can change a specific line of text in a listbox based on a condition.

For example, if I subract listbox.items.item(1) from listbox.items.item(0) and the posted result in position (2) is a negative decimal then make item(2) red.. or if the result is greater than 1000 then turn it green.

I tried some of the examples in some other posts, but they aren't what I am looking for.

Any help would be appreciated.

  As you can see, essentially this is a task where a ListBox contains some items that represent numeric values. Some simple arithmetic is used to calculate the value for the third line. The color of the text on that line is decided depending on whether the value is negative or higher than 1000.

  In Windows Forms this job would need the use of OwnerDraw in the ListBox, with each line being drawn using the GDI+ DrawString method. While not that daunting a task, OwnerDraw and DrawString can get a bit unwieldy if you have a lot of data to handle. So, even though OwnerDraw would probably be fine for this particular example, I still thought it was worth seeing how WPF might be used to deal with it.

  With my WPF head on, I first thought that I would tackle this with a value converter using IValueConverter, reading the values and setting the Brush color based on the value. But as it turns out, WPF's innate ability to accept varying settings for each individual ListBoxItem's Foreground property made it a much easier proposition.

The Basics

  Because I'm concentrating on the UI here, not the mechanics of how to get the values, I've short-circuited this part and simply hard-coded the values into the ListBox. (Don't worry, I'll get to how you can take values from the user, insert them into the ListBox and do the arithmetic at the end, if that's something you need.)

  Here's the Xaml to create the ListBox and those three items:

Code Copy
<Window x:Class="BasicTask"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="BasicTask" Height="300" Width="300">
    <Grid>
        <ListBox Margin="79,38,79,65" Name="ListBox1" FontSize="20">
            <ListBoxItem Name="Value1">2000</ListBoxItem>
            <ListBoxItem Name="Value2">3000</ListBoxItem>
            <ListBoxItem Name="Value3">-1000</ListBoxItem>
        </ListBox>
    </Grid>
</
Window>

  (I've manually done the arithmetic which is very unrealistic, but keeps the code to a minimum for now)

  Of the various ways of tackling this, I decided to use a simple Select Case block in the Code-Behind. The ListBox control has a LayoutUpdated event, which fires whenever there is a change to the layout of the visual elements of the control. We can use this event to apply the appropriate colors to the text items.

Code Copy
Partial Public Class BasicTask

    Private Sub ListBox1_LayoutUpdated(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.LayoutUpdated
        Select Case CDbl(Value3.Content)
            Case Is < 0
                Value3.Foreground = Brushes.Red
            Case Is > 1000
                Value3.Foreground = Brushes.DarkSeaGreen
            Case Else
                Value3.Foreground = Brushes.Black
        End Select
    End Sub
End
Class

  

   So if you already have a ListBox with values in it, that's all the code you need. It's quicker and cleaner than the OwnerDraw route, I think you'll agree.

Taking User Input

  As hard-coding those values in the Xaml isn't very realistic, as promised earlier, here is one way to create the ListBox in Xaml and update it in code:

Code Copy
<Grid>
        <Button Height="23" HorizontalAlignment="Left" Margin="22,91,0,0" Name="Button1" VerticalAlignment="Top" Width="75">Enter</Button>
        <TextBox Height="23" Margin="22,34,0,0" Name="TextBox1" VerticalAlignment="Top" HorizontalAlignment="Left" Width="84">2500</TextBox>
        <TextBox Height="23" Margin="0,34,31,0" Name="TextBox2" VerticalAlignment="Top" HorizontalAlignment="Right" Width="90">900</TextBox>
        <Label Height="28" HorizontalAlignment="Left" Margin="22,0,0,0" Name="Label1" VerticalAlignment="Top" Width="96">First Value</Label>
        <Label Height="28" HorizontalAlignment="Right" Margin="0,0,25,0" Name="Label2" VerticalAlignment="Top" Width="96">Second Value</Label>

        <ListBox Margin="0,91,31,33" Name="ListBox1" FontSize="20" HorizontalAlignment="Right" Width="120">
            <ListBoxItem Name="Value1">0</ListBoxItem>
            <ListBoxItem Name="Value2">0</ListBoxItem>
            <ListBoxItem Name="Value3">0</ListBoxItem>
        </ListBox>
</Grid>

Code Copy
    Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        Value1.Content = TextBox1.Text
        Value2.Content = TextBox2.Text
        Value3.Content = (CDbl(TextBox1.Text) - CDbl(TextBox2.Text)).ToString
    End Sub
    Private Sub ListBox1_LayoutUpdated(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.LayoutUpdated
        Select Case CDbl(Value3.Content)
            Case Is < 0
                Value3.Foreground = Brushes.Red
            Case Is > 1000
                Value3.Foreground = Brushes.DarkSeaGreen
            Case Else
                Value3.Foreground = Brushes.Black
        End Select
    End Sub

  The result will look something like this

  As you change the values in the two TextBoxes, the ListBox will update and the text color of the third item will reflect the rules in the LayoutUpdated event.

  Because the scenario has a preset configuration of just those three items, the above approach is the easiest.

Varying Number of ListBoxItems

  If for some reason you can't or don't want to create the three ListBoxItems in Xaml, then you can easily (if slightly more verbosely) do this in the code-behind:

Code Copy
Private Sub Button1_Click(ByVal sender As Object, ByVal e As System.Windows.RoutedEventArgs) Handles Button1.Click
        ListBox1.Items.Clear()

        Dim lbi As New ListBoxItem
        lbi.Content = TextBox1.Text
        ListBox1.Items.Add(lbi)

        lbi = New ListBoxItem
        lbi.Content = TextBox2.Text
        ListBox1.Items.Add(lbi)

        lbi = New ListBoxItem
        lbi.Content = (CDbl(TextBox1.Text) - CDbl(TextBox2.Text)).ToString
        ListBox1.Items.Add(lbi)

        Dim item3 As New ListBoxItem
        item3 = CType(ListBox1.Items(2), ListBoxItem)

        Select Case CDbl(item3.Content)
            Case Is < 0
                item3.Foreground = Brushes.Red
            Case Is > 1000
                item3.Foreground = Brushes.DarkSeaGreen
            Case Else
                item3.Foreground = Brushes.Black
        End Select

    End Sub

  You can of course vary the number of ListBoxItems added in this way and select another of them for the text color formatting treatment. You'll see that I put all the code in the Button click this time. If you're wondering why, it's because the LayoutUpdated event fires when the ListBox is first created. As there are no ListBoxItems in existence at that moment, you will get an exception when you try and access the non-existent ListBox1.Items(2) item.

And Finally ....

  Although it's not part of the original question, you might at some time want to comb through a ListBox like this and change the color of all the lines that meet our criteria of less than zero or more than 1000. Enumerating through the ListBoxItems will do this job for you:

Code Copy
  Private Sub ListBox1_LayoutUpdated(ByVal sender As Object, ByVal e As System.EventArgs) Handles ListBox1.LayoutUpdated
        For Each l As ListBoxItem In Me.ListBox1.Items
            Select Case CDbl(l.Content)
                Case Is < 0
                    l.Foreground = Brushes.Red
                Case Is > 1000
                    l.Foreground = Brushes.DarkSeaGreen
                Case Else
                    l.Foreground = Brushes.Black
            End Select
        Next
    End Sub

  And as a final thought, if you only want to turn text Red if the value is below zero and leave it as Black for all other values then you can replace that multi line Select Case block with a single line IIF statement.

  For completeness, all the above samples should have some validation added to ensure that the items exist and that the text represents valid numeric values.

posted @ 1:31 PM | Feedback (0)

First Chance Exceptions

  I suspect that most of us have become so used to seeing the message that reads:-

" A first chance exception of type 'System.ApplicationException' occurred in WindowsApplication1.exe "

 that it hardly hits our conscious thoughts any more.

  But did you ever check out just what this message really means or wonder whether you should or could do anything about it ?

  I suppose the first thing you need to know in order to answer those questions is just exactly what a First Chance Exception is. Well, in it's simplest terms it's a mechanism that flags up that there is a possible error condition. The key point here though is that this flagging up takes place in the Debugger and not in the running application itself. (We probably often think of the two as being the same thing, but in fact that's not really the case).

  When the Debugger detects an Exception situation it raises a First Chance Exception. In several situations it isn't always desirable for the program to come to a grinding halt each time. And of course, being a skilled developer, you will have built appropriate Try Catch exception handling blocks into the code which will sort the problem anyway! So, depending on the Debugging settings you have laid down (more on this later), the Debugger allows this First Chance Exception to pass and the program continues to run.

Second Chance Exceptions

   At this point, where the running program now has to deal with the Exception situation, the application will either handle the Exception or not handle it (your Structured Exception Handling code coming in to play here). If it does handle it, then the application will of course be allowed to proceed and it will happily keep running until the next problem is encountered or the application ends.

  If the program fails to deal with the Exception at this point, the Debugger is notified again of this unhandled error situation - and this is now the Second Chance Exception level. Hitting this point will result in the kind of Unhandled Exception Message Box that I know you will have seen many, many times:

An Exceptional Situation - XamlParseException

  Although I'd never really given it much thought I guess I'd always assumed that by default the settings in Visual Studio were such that all First Chance Exceptions were allowed through to the program as described above. With some timely assistance from the Microsoft Visual Basic team, I discovered recently that this is not the case. There is one Exception which by default is set to Throw on a First Chance Exception - and that is the XamlParseException.

   When I say "by default" I'll have to qualify that slightly. I'm not sure that it is set by default in every kind of installation of Visual Studio 2008, but certainly in the Pro and Express Editions if you have set the Profile to Visual Basic developer settings then this will be the case.

  As a result I spent quite a long time struggling with a particular project that had to deal with many situations where the Xaml at certain points in time was not valid and so would not parse. Even though I had built in a Try Catch block for this Exception, the program would never reach that exception handler because the Debugger would throw the Exception at the first chance stage.

  The route to finding this setting in the IDE is as follows:

Select Debug > Exceptions
then in the Window that appears, choose "Common language Runtime Exceptions" and expand the list.
Navigate down the list until you reach "System.Windows.Markup".
Next click on the plus symbol to show the Exceptions in this class.

  (Alternatively you can click the "Find..." button and enter the name of the Exception).

  You can see in the screenshot below that the "Thrown" checkbox is checked:

 which is of course the reason why my project was stopping in Debug mode whenever it first hit a XamlParseException.

  If you want your code to be allowed to handle this kind of Exception (as I did) then of course you just need to uncheck that box.

  I did a quick sweep of all the settings for all Exceptions and that XamlParseException seems to be the only one that is checked by default. But if you should come across a similar puzzling situation yourself in the future, you should probably think of those Exception settings as one of the places you should first look.

posted @ 11:44 AM | Feedback (0)

Sunday, January 20, 2008 #

   I've been experimenting with the interaction between Visual Studio 2008 and Expression Blend (Version 1 with SP1). One thing I realised early on (right from the Orcas Beta days) is that Blend is a great help when you want to fine tune color gradients, create lines, shapes and paths or create animations. Having carried out both of these tasks by typing in the Xaml code in Visual Studio and checking the result, it's not something I'd want to do the hard way long term.

  That said, I'm surprised at just how comfortable I am now with manually entering xaml in Visual Studio for the mainstream tasks - probably because this is the way I started. In fact, because the early Beta designer had poor toolbox functionality I still often prefer to type xaml, rather than drag an instance from the toolbox. (I'm sure I'll get lazier as time goes on, though!).


  I didn't find Blend very intuitive at first (and positively hated the default "Expression Dark" setting). But I'm beginning to find that I'm using the Properties and Interaction Panels much more now, so I suppose it's just another learning curve to navigate.

  Anyway, back to the interaction between the two products. If you open up the same project in both Blend and Visual Studio at the same time you can flip back and forth between the two. Whenever you save file(s) in either application, you'll be invited to update the modified project as soon as you switch to the other app. Note that the files have to be saved, not just amended, for this to happen.

   I made a couple of wrong assumptions at first. One thing I did wrong was to open up individual xaml files from an existing project in Blend to work on them (i.e I opened a new Blend project and added an existing file to that). Of course, the only sensible way is to open the containing Project, even if you aren't currently interested in working with it in Visual Studio.


  You can make changes (if you want to) to any of the xaml files inside Blend, save the file(s) and exit. The next time you do open up this project in Visual Studio, the changes will be incorporated (naturally, because it's the same files!) but you won't get any notification that changes have been made. The same applies in reverse.

  It's possible that you might be tempted to select a .vb or .cs file, right click and select "Edit Externally" from the Context Menu, or double click the file name. And if you did this, you might expect to be taken to the Visual Studio instance that's currently running this project. Actually what does happen is that a new instance of Visual Studio will open with just that single code-behind file in the IDE. So of course most times you'll just Alt-TAB between applications or use the Windows Taskbar.

  

  On the subject of editing externally, you'll absolutely want to stick with Visual Studio for most of your xaml editing. Blend offers you no Intellisense help at all in the current version; VS Intellisense is very smart and helpful. If you choose the 'Edit Externally' option in Blend, you'll be taken to Notepad by default, which isn't a whole lot better than the xaml window in Blend itself. It may be possible to tweak this setting to some other xaml code editor such as XamlPad, but it's hard to see any reason not to use Visual Studio if you have it.

  So essentially my experience so far is that the best way is to open the same project side by side (literally in my case as I now use two monitors), use Visual Studio for most of the hand-built xaml (plus the code-behind of course) and use Blend for the purely visual touches that are difficult to visualize and/or verbose to write. If V2 of Blend includes Intellisense that might change but for now that's the approach that works best for me.

posted @ 8:42 PM | Feedback (0)

Wednesday, January 16, 2008 #

  Or at least it looks as though the animals definitely rule on the new site Pet-Files.

  It looks like a kind of Facebook for Pets - maybe that should be Facebark - where you can post up pictures of your pets and have a chat with other pet owners, swapping stores, getting advice, etc.

  Long time friend of vbCity, Marco Bellinaso who - when not writing top class books - likes to spend quality time with his pets, is the man behind the site.  So if you have a pooch, pussy, pigeon or parrot and you want somewhere to show them off to like-minded pet lovers then  maybe Pet-Files will be the place to go.

  Knowing Marco's web application background, I'm guessing there'll be a few asp devotees around the site too. 

 

posted @ 2:46 PM | Feedback (0)

Tuesday, January 15, 2008 #

   Adding controls at run time using VB.NET in Windows Forms is fairly well-documented. Finding C# code-behind samples for doing this with WPF controls under Framework 3.0 is also an easy task.
But I recently wanted to see how to do this with a WPF application in Visual Basic 2008 and I found that at the time of writing my searches produced no useful clear "How To" results.

   Direct conversion from C# to VB using the current conversion tools didn't always identify some essential code elements, resulting in quite a frustrating time spent finding the correct way of doing this. (Not an unusual scenario nowadays, as more and more samples - including too many MSDN ones - seem to have only C# samples available).

  Along the way I also discovered that not everything is as it seems - apparently difficult things were easy; things that seemed they should be easy turned out to be more difficult.
And of course as is often the case it turns out that there is more than one way to do most things.

   Once you have solved the puzzles it all seems easy, but I thought I'd save you the trouble of having to work out the steps involved if you should need to do this before better Visual Basic documentation becomes available.

  You can link to the first page of my article here.

posted @ 6:17 PM | Feedback (0)

  I've bought several books on Windows Presentation Foundation over the past few months and I've reviewed a couple of them already. As is usually the case, each of the books has something to offer and it's a rare day when you can find all the information you need on a complex, wide ranging topic like WPF in one book.

  Without detracting from the other books that I admire, I think if one book does come closest to being a one-stop source then possibly it is the Pro WPF book by Matthew MacDonald. As with all his books, coverage of topics is comprehensive, detailed and accurate. At just under 1000 pages it's definitely a heavyweight, although you're unlikely to want to be parted from it long enough to use it as a doorstop.

  The author's writing style is friendly without being patronising. There are no cartoons or corny jokes, but screen shots are used where appropriate and his approach is light and easy to follow - not an easy achievement in a topic as complex as WPF.

  If I have a gripe about the book, it's the same complaint I've been making since the middle of 2007 - this is yet another WPF book that only has code behind samples in C#. (And in the case of this particular publication that's a piece of information the publishers chose not to mention on the cover). That said, the samples are still clear and I had very little difficulty translating to VB.NET where necessary. Bearing in mind that much of the new material you need to get to grips with in WPF is on the XAML side, this isn't quite as big a problem as it could have been.

  Of the books I have on WPF, I turn to this one early in most researches - although as you'll have gathered from my earlier comments, searching for answers while maneuvering through the WPF minefield almost always involves more than one book, often plus an online search. On the subject of search access, Apress offer a PDF version of this book for an additional $10. For a book with this amount of content it's tempting. However, if you need to preserve your cash, the Index in this book is in fact particularly good. There's definitely something to be said though for being able to take a snippet of information you think you read in the book somewhere and do a trawl through the PDF version to home in on it.

  Still with cash preservation in mind, I see that the Second Edition is due out early in 2008, this one updated for the 3.5 Framework, so you may want to wait for that one to appear on the shelves. I also note that a VB.2008 version of this new edition is on the schedule, but there is no publication date announced yet, so it's not likely to be any time soon.

   I didn't see a Contents list on the Apress web site, so I'll list the chapters below:

  • Introducing WPF
  • XAML
  • The Application
  • Layout
  • Content
  • Dependency Properties and Routed Events
  • Classic Controls
  • Windows
  • Pages and Navigation
  • Commands
  • Resources
  • Styles
  • Shapes, Transforms and Brushes
  • Geometries, Drawings and Visuals
  • Control Templates
  • Data Binding
  • Data Templates, Data Views and Data Providers
  • Lists, Trees and Menus
  • Documents
  • Printing
  • Animation
  • Sound and Video
  • 3-D Drawing
  • Custom Elements
  • Interacting with Windows Forms
  • ClickOnce Deployment

  As I say, it's comprehensive. All in all, I consider this book to be a good investment. I have several of Matthew MacDonald's earlier books, which I have always found relevant, well-written and useful; this book is in the same mould.

posted @ 5:40 PM | Feedback (1)

Monday, January 14, 2008 #

  I've noticed a couple of questions in the VB.NET forums recently where someone wants to change the BackColor of the Tab Header on TabPages. As far as I know, in VB2005 and earlier you have to either use OwnerDraw techniques or subclass your own version of a TabControl.

   In VB2008, WPF offers a much easier route. The equivalent element to a TabPage in Windows Forms is the TabItem in WPF. The WPF TabItem actually has its own Background and Foreground properties, each of which will be applied to the Header Tab.

Of course you can also set the Background color of the main TabItem page itself via panel type controls with their own Backgrounds set as required. The ListBox in the screenshot demonstrates this.

  The following sample is a very basic example of doing this.

Code Copy
   <TabControl Margin="8" Name="TabControl1">
      <TabItem  Header="Members" Background="LightGreen"
       Foreground
="Navy">

        <Grid>
          <ListBox Width="150" Background="LightGreen"
                   HorizontalAlignment="Left">
            <ListBoxItem>J Smith</ListBoxItem>
            <ListBoxItem>J Jones</ListBoxItem>
            <ListBoxItem>C B Travis</ListBoxItem>
            <ListBoxItem>L Fourleather</ListBoxItem>
          </ListBox>
        </Grid>
      </TabItem>

      <TabItem Background="Green" Header="Associates"
       Foreground
="Navy" >
      </TabItem>

      <TabItem Background="LightBlue">
                <TabItem.Header>
                    <StackPanel Orientation="Horizontal" >
                        <Image Width="20" Source="CLUB.BMP"/>
                        <TextBlock Text="   Sponsors" Foreground="Red"/>
                    </StackPanel>
                </TabItem.Header>

                <Grid>
                    <ListBox>
                        <ListBoxItem>J Smith</ListBoxItem>
                        <ListBoxItem>J Jones</ListBoxItem>
                        <ListBoxItem>C B Travis</ListBoxItem>
                        <ListBoxItem>L Fourleather</ListBoxItem>
                    </ListBox>
                </Grid>
            </TabItem>

    </TabControl>

  The result looks like this:

  One thing to note is that by default the Header will revert to a White background when it has focus (as shown in the above screenshot). A side effect of this is that you have to be aware that your Foreground will also need to be such that it is visible on both a white background as well as the one you set. To change this behaviour you will probably have to apply a Style or use a ControlTemplate. I haven't fully researched this yet, but plan to write a full article on TabControls and these little tips and tricks in the very near future. But in the meantime if all you need is a more colorful set of headers then WPF supplies the easy answer.

posted @ 2:27 PM | Feedback (3)