Posts Tagged ‘WPF’

WPF book has been released and Silverlight book will be available on 28th of August

Monday, July 12th, 2010

Exactly two years after the first release of the WPF-book the second edition is available since some days. Find more details about the content and where you can order it on http://www.thomasclaudiushuber.com/wpf.

The Silverlight-Book has also been written and is currently running through the process of reading, testing and printing. It will be in stores on 28th of August. Find more information about the Silverlight-Book and where you can order it on http://www.thomasclaudiushuber.com/silverlight.

I hope you like the books and you can master the “programming-challenge” of your wpf- and silverlight-projects with the knowhow you got from the books.

Cheers,
Thomas

Visual Studio has been released, Silverlight 4 has been released and the books are on their way…

Saturday, April 17th, 2010

After Visual Studio has been released on Monday this week, Silverlight 4 is also available since Thursday. I’ll have to speed up my book-writing. As many of you know, I’m writing on a second edition of my WPF-book to .NET 4.0 and Visual Studio 2010. I’m also writing on a Silverlight-book (about Silverlight 4.0). Below some details of the two books.

The WPF-Book:

I’ll finish the update of my WPF-book till end of April, so it’ll be released in June. There are many new things in it, like a section to the Model-View-ViewModel-Pattern, Multitouch, the new Controls DatePicker, Calendar and DataGrid, Animation Easing-Functions, VisualStateManager, Windows 7 Taskbarintegration, Pixel-Shaders and much more. Of course there’s also a new version of the FriendStorage-Application that is using new features and controls, like e.g. the DataGrid:

01_06

FriendStorage now also has integration into the Windows 7 Taskbar. So you can iterate through the friends via the Buttons shown in the Windows 7 Taskbar Thumbnail. Also recognize that the image of the current friend is also displayed as overlay-image on the Taskbar-Button

image 

You find the second edition of my WPF-book here on amazon.de

The Silverlight-book

I’ll write on the Silverlight-book till end of June, so it’ll be released in August. I hope you’re looking forward to it. I gave and will give my best that it’s a great resource to all professional Silverlight-Developers and those who want to become one of those. In May I’ll show the contents of the Silverlight-book on my homepage. I’ll also blog here. For now I can say that there’s a FriendStorageOnline-Application in the Samples with Login/Registration and CRUD-Operations via WCF Ria Services. A logged-in User can create Friendlists and insert data as usual. The app looks like this:

01_04

The Silverlight-book is also already on amazon here. But keep in mind that there could be a change in pages (some more up to 1000) and so maybe also in price. I’ll post more information about the targeted pagecount in May, then you’ll also see some details of the contents.

Ciao,
Thomas

BASTA! Spring 2010 ::: WPF 4.0 – Die Neuerungen im Überblick

Thursday, February 25th, 2010

Danke für die zahlreiche Teilnahme an meiner Session zu den Neuerungen in WPF 4.0. Ich hoffe, es hat allen Spass gemacht und jeder konnte etwas mitnehmen. Folgend die versprochenen Slides und Demos:

Slides
Demos

Happy Coding,
Thomas

BASTA! Spring 2010 – Model-View-ViewModel

Wednesday, February 24th, 2010

Hallo liebe Freunde der BASTA!, VB.NET'ler und Teilnehmer an meiner Session zum Model-View-ViewModel-Pattern. Folgend die versprochenen Slides und die Beispielanwendung zum Download.

Slides
MVVM.BeispielApp

Viel Spass damit,
Thomas

Be careful with Default-Values of Dependency-Properties if you’re using Reference-Types.

Thursday, February 11th, 2010

I’ve justed finished a small PieMenu for a WPF-Application for one of our customers in switzerland. The PieMenu is displayed below with a black-red-style. The Style, colors and items can be changed individually. The colors and icons etc. in the PieMenu below are just the ones I’ve created for testing purposes.

image

While developing this PieMenu I’ve implemented several Dependency-Properties. Some of them containing ObservableCollections as Default-Values like this:

static PieMenu()
{
 LeftSubItemsProperty = DependencyProperty.Register(
  "LeftSubItems", typeof (ObservableCollection<PieMenuItem>),
  typeof (PieMenu), new UIPropertyMetadata(
  new ObservableCollection<PieMenuItem>()));
  …
}

I developed, made some UI-Tests, developed, made some UI-Tests and so on and everything was fine. But only till I’ve placed a second PieMenu in my Test-App. All Items of PieMenu1 and PieMenu2 were contained in PieMenu1 and PieMenu2. If you see the line above you can image what happened, if you sit in front of your code with at least 1000 lines of code in the PieMenu-class, you have to search a bit.

In the line above the ObservableCollection created as a Default-Value for the Dependency-Property is of course a static one, because the Dependency-Property is stored in a static variable and as you see in the code-snippet above it is initialized in the static constructor of the PieMenu-class. There’s no instance around at this point.

In other words that means every PieMenu that won’t explicitly specify an ObservableCollection gets the Default-Value, and that’s a static one that will be shared over all PieMenus in your app. So all the Items of every PieMenu are in every PieMenu. Isn’t that amazing? :-)

The solution I’ve used is straight forward. Just create the Dependency-Property with a null-reference as its default-value:

static PieMenu()
{
 LeftItemProperty = DependencyProperty.Register(
  "LeftItem", typeof (PieMenuItem), typeof (PieMenu),
  new UIPropertyMetadata(null));
}

In the Instance-Constructor assign a new ObservableCollection to the Dependency-Property and you’re fine.

public PieMenu()
{
 LeftSubItems = new ObservableCollection<PieMenuItem>();
 …
}

Keep in mind that setting a local value in the Constructor won’t let you set this value in a Style anymore. But for the PieMenu and the ObservableCollection that won’t matter. You’re just adding and removing elements, you don’t want to define this Collection in a Style.

So, as you see in this post, you’ve to implement Dependency-Properties with Default-Values that are reference-types with caution.

Happy coding! ;-)

WPF Printing: How to print a PageRange with WPF’s PrintDialog - that means the user can select specific pages and only these pages are printed

Tuesday, November 24th, 2009

Printing a Page Range isn’t as easy as it supposed to be. So in this blog-post you’ll see a very easy method to print specific pages from a XPS-Document. But before we look at the solution, let’s start with the problem.

The Problem

WPF’s PrintDialog has a UserPageRangeEnabled-Property. Set this property to true before you show the PrintDialog. Then the user is allowed to enter a Pagerange in the PrintDialog. The problem is that whatever the user enters, in each case all pages are printed. The PrintDialog itself has no logic to print some specific pages. Let’s look at an example.

Below the small UI that consists of a Button and a DocumentViewer. This code belongs to the MainWindow.xaml-File.

<Button Content="Print" Click="PrintButtonClick"
        Margin="10"
        HorizontalAlignment="Left"
        Width="75"/>
<DocumentViewer x:Name="viewer" Grid.Row="1"/>

The Codebehind-File MainWindow.xaml.cs has an EventHandler for the Loaded-Event of the Window. There a XPS-Document with five pages is loaded into memory. The FixedDocument-Instance contained in that XPS-Document is stored in the _fixedDocument-Field and displayed in the DocumentViewer called viewer – the latter we declared above in XAML.

public partial class MainWindow : Window
{
 private FixedDocument _fixedDocument;

 public MainWindow()
 {
   InitializeComponent();
 }

 private void OnLoaded(object sender, RoutedEventArgs e)
 {
    // Load the FixedDocument
  var document = new XpsDocument("FivePagesDocument.xps",
                                   FileAccess.Read);
  var sequence = document.GetFixedDocumentSequence();
  _fixedDocument = sequence.References[0].GetDocument(false);

    // Assign it to the viewer
  viewer.Document = _fixedDocument.DocumentPaginator.Source;
 }

So we have the necessary thing for testing a “print-range”-scenario: A FixedDocument-Instance in memory, stored in the _fixedDocument-Field. Let’s look at the PrintButtonClick-Eventhandler that contains the logic to print. The Eventhandler is shown below. First a PrintDialog is created. Then we set the UserPageRangeEnabled-Property to true, show the Dialog by calling the ShowDialog-Method. Is the return-value true we call the PrintDialog’s PrintDocument-Method by passing in the DocumentPaginator of the FixedDocument. Also a string is passed in that is displayed in the printer queue as jobname.

void PrintButtonClick(object sender, RoutedEventArgs e)
{
  var dlg = new PrintDialog();

  // Allow the user to select a PageRange
  dlg.UserPageRangeEnabled = true;

  if (dlg.ShowDialog() == true)
  {
    DocumentPaginator paginator =
      _fixedDocument.DocumentPaginator;
    dlg.PrintDocument(paginator, "Just a test");
  }
}

Now what happens? Let’s look how we use the application. When starting up the application, the FixedDocument with five pages is displayed in the DocumentViewer:

image

When the “Print”-Button is pressed, the PrintDialog comes up. I select a PageRange of 2-3 like shown below. For testing purposes I always print in the PDFCreator that creates a PDF-Document with the output. There are several other ways. You could also print in the XPS-Document-Writer (even if it’s a little bit doubled when printing a xps to the XPS-Document-Writer).

image

Now even with the Pages of 2-3 selected, the “printed” PDF looks like below. It contains all five pages of my document. But it should contain only the pages 2 and 3.

image

So let’s summarize the problem: It doesn’t matter what you select as a PageRange in the PrintDialogs Pages-Field. It’s up to you to check the Pages and print out only that range. The PrintDialog doesn’t care anything about the PageRange.

The PrintDialog has the Property PrintRange that contains a PrintRange–object with PrintFrom- and PrintTo-Properties. It also has a Property called PageRangeSelection that contains the value PageRangeSelection.UserPages when a PageRange was entered. But the logic to print out that specified range is your work. And this work needs some WPF know-how to do. So let’s look at the solution(s). :-)

A bad solution

I call the first one a bad solution because it is not an easy to manage one. This solution is to make a new FixedDocument that only contains the pages you need. You can implement such a logic based on the things you find in this codeproject-article:

http://www.codeproject.com/KB/vb/reording_xps.aspx

In my mind creating a new XPS-Document just for printing is a bad solution. I think a good solution would be to just be able to print some pages of an existing xps-Document/FixedDocument. So let’s look at the good one.

A good solution (I hope so ;-))

The good solution is the one I’ve implemented today and finished in the train from Zurich to Basel. I’ve not tested every scenario, but it seems to work great. If you have any hints to this solution, let me know.

The first thing you have to know is that the pages used for the output are created by a DocumentPaginator. This was passed to the PrintDocument-Method of the PrintDialog some lines above. The DocumentPaginator-class itself is abstract. Beside some members it defines a Method GetPage(int pageNumber) that returns the DocumentPage for the passed in pageNumber. Now the idea is to create a wrapper-class for the DocumentPaginator that is itself also of type DocumentPaginator. And now guys, what pattern is that? ;-) Doesn’t matter.

So we create a DocumentPaginator and let’s call it PageRangeDocumentPaginator. It encapsulates a DocumentPaginator and can return a specific (page)range of the encapsulated DocumentPaginator. Therefore the constructor takes two parameters: a DocumentPaginator to encapsulate and a PageRange-object that contains PageFrom and PageTo-Properties, both of type int. The PageRange-structure exists in the Namespace System.Windows.Controls.

The PageRangeDocumentPaginator-class is listed below. In the constructor the passed in DocumentPaginator is stored in the _paginator-field. The pageRange-values are stored in the fields _startIndex and _endIndex. As the PageRange starts with 1, we substract 1 to get the zero-based index. In the final line of the constructor the _endIndex is adjusted. If the user enters a higher pageNumber than the Document contains, _endIndex will point to the index of the last page.

Now look at the override of the GetPage-Method. There gets just the GetPage-Method of the encapsulated DocumentPaginator called. But the _startIndex is regarded. Now look at the PageCount-Property. It uses the _startIndex and _endIndex to calculate the pageNumbers. IsPageCountValid always returns true and the Properties PageSize and Source simply pass the responsibility to the underlying DocumentPaginator. That’s it. Now look how to use the class in the PrintButtonClick-Eventhandler.

/// <summary>
/// Encapsulates a DocumentPaginator and allows
/// to paginate just some specific pages (a "PageRange")
/// of the encapsulated DocumentPaginator
///  (c) Thomas Claudius Huber 2010
///      http://www.thomasclaudiushuber.com
/// </summary>
public class PageRangeDocumentPaginator : DocumentPaginator
{
  private int _startIndex;
  private int _endIndex;
  private DocumentPaginator _paginator;
  public PageRangeDocumentPaginator(
    DocumentPaginator paginator,
    PageRange pageRange)
  {
    _startIndex = pageRange.PageFrom - 1;
    _endIndex = pageRange.PageTo - 1;
    _paginator = paginator;

    // Adjust the _endIndex
    _endIndex = Math.Min(_endIndex, _paginator.PageCount - 1);
  }
  public override DocumentPage GetPage(int pageNumber)
  {
    // Just return the page from the original
    // paginator by using the "startIndex"
    return _paginator.GetPage(pageNumber + _startIndex);
  }

  public override bool IsPageCountValid
  {
    get { return true; }
  }

  public override int PageCount
  {
    get
    {
      if (_startIndex > _paginator.PageCount - 1)
        return 0;
      if (_startIndex > _endIndex)
        return 0;

      return _endIndex - _startIndex + 1;
    }
  }

  public override Size PageSize
  {
    get{return _paginator.PageSize;}
    set{_paginator.PageSize = value;}
  }

  public override IDocumentPaginatorSource Source
  {
    get { return _paginator.Source; }
  }
}

The PrintButtonClick-Eventhandler just needs a little if-statement. The PrintDialog has a Property called PageRangeSelection of Type PageRangeSelection (Enum). The PageRangeSelection-Enum contains the values AllPages and UserPages. When the User has entered a PageRange, that Property would have the value UserPages. In that case I use the PageRangeDocumentPaginator-class and pass in the DocumentPaginator of the FixedDocument and the PageRange from the PrintDialog. If the PageRangeSelection-Property contains not the value UserPages, we print all pages as we’ve already done in the problem-scenario. So the code looks like this:

void PrintButtonClick(object sender, RoutedEventArgs e)
{
  var dlg = new PrintDialog();

  // Allow the user to select a PageRange
  dlg.UserPageRangeEnabled = true;

  if (dlg.ShowDialog() == true)
  {
    DocumentPaginator paginator =
      _fixedDocument.DocumentPaginator;

   if (dlg.PageRangeSelection == PageRangeSelection.UserPages)
   {
     paginator = new PageRangeDocumentPaginator(
                      _fixedDocument.DocumentPaginator,
                      dlg.PageRange);
   }

    dlg.PrintDocument(paginator, "Yes, it works");
  }
}

When the user has selected a PageRange the PageRangeDocumentPaginator is used to generate the pages for the output. When I test the code with a PageRange of 2-3 as in the problem-section, I now retrieve the expected output of the two pages 2 and 3, as my “printed” PDF shows:

image

That’s it. Enjoy the code and download the solution here. And don’t forget to kick this post for me:

[Download Thomas PrintingProject]

kick it on DotNetKicks.com

Cheers Thomas

PS: As time and my sparetime is limited - I’m writing on my Silverlight 4.0 book and an update of my WPF book in my sparetime - I can’t give any free support for the code. Use it or not. But feel free to contact me for any suggestions via:

http://www.thomasclaudiushuber.com/contact.php

Hey Thomas, what’s coming up next?

Saturday, October 31st, 2009

I’ll give you just a short information of what is coming up next and what I did the last months. Let’s start with the things coming up…

… what’s coming up next:

  • WebTech-Conference – 16th November, Karlsruhe/Germany
    Another talk about datadriven Silverlight-Applications. Meet me at this conference for discussions about WPF, Silverlight, .NET in general, my books and other topics. Find more about the WebTech-conference on webtech
  • Update of the WPF-book to .NET 4.0 and Visual Studio 2010
    The WPF-book was written about .NET 3.5. Next year .NET 4.0 will be released. There are many new things introduced in WPF. The DataGrid- and DatePicker-Control, VisualStateManager, Animation Easing Functions, Layout Rounding and so on. I’m working on an update of the book that will be released next year shortly after the German Visual Studio Release.
  • Writing a german book about Silverlight 4
    Currently I’m working hard on my book about Silverlight 4. I’ve already written about 300 pages. The book will be released next year shortly after the Silverlight 4 release. There are no comments on the Silverlight 4 release, but at PDC in mid-November there’s a session about the Silverlight-Roadmap. Then we’ll know more. So stay tuned. Find more about the upcoming Silverlight-Book on the new silverlight-category on my homepage

… what I did the last months:

  • Silverlight-Articles
    I’ve written six articles about Silverlight for the German dotnet-magazine. Download the articles beside others on www.thomasclaudiushuber.com/articles.php.
  • PrioConference – 28th October, Munich/Germany
    I had a session about datadriven Silverlight-Applications. Find the Details on the new talks-category on my homepage.

So stay tuned. If you’ve any questions, leave a comment or write me an email via the contact-form on my homepage.

Thomas

WPF-Book on top in C#-Category

Thursday, August 27th, 2009

Even if it was maybe just for one hour, I’d like to say “Thank you” to all my readers for pushing the book up to the first place in the C#-Category on amazon.de.

Cheers Thomas 

image

WPF "Advanced Layout"-Session at BASTA

Saturday, February 21st, 2009

Next week you can meet me at the BASTA - a German Conference about .NET, Visual Studio & more. I’ll give a presentation about Layout-functionality in WPF on Tuesday at 13.30 o’clock. After the presentation you can meet me (on Tuesday only) and other "Trivadians" (the whole week) at the "Trivadis"-stand.

I’m looking forward to see you there. :-)

The Lottery-Console-Application used at the last WPF-Event @ Microsoft Usergroup Switzerland

Monday, August 25th, 2008

Last week we had a great WPF-afterwork-event at Microsoft Usergroup Switzerland (MSUGS) sponsored by Trivadis. I gave a deep-dive session about developing custom controls using WPF with many of it’s features like Dependency Properties, Commands, Routed Events, PART-Elements, Theme-Styles and so on.

At the end of the session a copy of my German WPF-book was drawn. We made a small lottery, but not a normal one. As all attendees were .NET-developers, everyone trusted in .NETs Random-class, so why don’t do it just in code?! We’ve written life a small console-application that did the job for us. As some people asked for the code (of course only the loosers and not the winner of the book ;-) ), here it is:

static void Main(string[] args)
{
  Console.WriteLine();
  Console.WriteLine("  — MSUGS- WPF-Book Lottery");
  Console.WriteLine("  Enter names and a dot (\".\")"
                  + " when names are complete");
  Console.WriteLine();

  List<string> names = new List<string>();
  Console.Write(">");
  string name = Console.ReadLine().Trim();

  while (!name.Equals("."))
  {
    names.Add(name);
    Console.Write(">");
    name = Console.ReadLine().Trim();
  }

  Random random = new Random();
  int winnerIndex = random.Next(names.Count);

  string winner = names[winnerIndex];

  Console.WriteLine();
  Console.WriteLine("Starting lottery…");

  Thread.Sleep(3000);

  Console.Write("And the winner is");

  for (int i = 0; i < 10; i++)
  {
    Thread.Sleep(1000);
    Console.Write(".");
  }
  Console.WriteLine();
  Console.WriteLine();

  Console.WriteLine(winner);

  Console.ReadLine();
}

The Console-Application looks like this:

image

The lucky winner at the MSUGS-event was Stefan, he was at index zero in the names-Collection. Congratulations!

st_msugs_080820

Thanks to MSUGS for the great organization and to all developers who attended in the session. I hope you enjoyed it.