Syndicate

News

Recent Comments

5/15/2008 at 1:37 PM

Really interesting, but I did not know already the...
by alkampfer

Read more...

5/13/2008 at 3:54 PM

Hi Marco,I appreciate that the DataContext propert...
by Derek Lakin

Read more...

5/12/2008 at 12:47 PM

Well Alk, for example ListView has no direct suppo...
by Marco De Sanctis

Read more...

5/12/2008 at 12:38 PM

Hi Derek, thanks for your feedback.DataContext is ...
by Marco De Sanctis

Read more...

5/12/2008 at 11:21 AM

Well, who cares about datagrid with the ListView :...
by alkampfer

Read more...

Recent Posts

Create a WPF skinnable ImageUploader control

5/15/2008 at 1:12 AM

Read more...

Cool, professional (and free!) WPF controls

5/12/2008 at 10:37 AM

Read more...

Beware the XamlParseException...

5/12/2008 at 8:43 AM

Read more...

WPF best practices: decoupling behavior from the view

5/9/2008 at 6:28 PM

Read more...

Bind a Linq Binary type to ImageSource

5/8/2008 at 12:37 AM

Read more...

Archives

May, 2008 (7)

Post Categories

Misc
WPF
LINQ

In a previous post, I showed how you can directly bind a Binary LINQ type to a WPF Image control implementing an ad-hoc type converter, not so much useful unless you don't have your images already stored on your database. What we need is something that is capable to achieve a two way binding, both displaying images and allowing users to upload their own; what about a brand new, completely skinnable, WPF custom control? So, let's create a new WPF project and add a new CustomControl called ImageUploader and take care of its logic first. As I wrote elsewhere, it's a good practice to design control's behavior (and implement it) without references to any UI element.

First of all, we need a property where to store an ImageSource object; we want it to be two-way bindable, so we are going to build a dependency property instead of a plain CLR one with appropriate FrameworkPropertyMetadataOptions:

image

Next, we need a couple of commands:

  1. a Clear command (we want the user being able to remove the current image)
  2. a Browse command to upload a new picture

If you've read some posts of mine, lately, you should perfectly know how to create custom commands and bind them to handlers smile_regular

image

The ClearImageCommand handler is pretty straightforward:

image

Same for the BrowseCommand handler, although it deserves one little note: we could obviously use the BitmapImage constructor with a URI as argument to directly reference the file; however this approach leaves the file locked for the whole BitampImage lifetime (which unfortunately ends only when GC wants to). Therefore what we do is manually handling its loading, setting the CacheOption property to load the entire image data during its init stage and caching it in a MemoryStream:

 image

Now that our control's logic is completely defined (and, again, without references to any UI element), we can move to creating a default layout on the generic.xaml file; a very simple one could be the following

image

that is not so bad if we add a bit of animation...

Anyway, doing something fancier is only a matter of Blend skills (and mine are awful).

One last note: the BinaryToImageConverter I showed you here is still one-way only. To get it work in both directions, we must implement the ConvertBack method:

image

image Here's the complete source code, obviously released under the "Works on my machine" license smile_wink

Enjoy!

kick it on DotNetKicks.com

Today I saw a post of a friend of mine about WPF lacking some of the controls we used to have in Windows Forms (who said DateTimePicker? or was it DataGrid?). Indeed, there are many Open Source project to fill the gap, like AvalonControlsLibrary or WPF Toolbelt, but beside that, Xceed has an excellent DataGrid (although not so straightforward to use) which has a free express edition that can be used even in commercial apps.

The cool thing is that the package includes a bunch of other useful controls, like a DateTimePicker, a MaskedEditTextbox, and so on, that can be obviously used on their own. Moreover, everything is well documented and with many samples.

Uh... I was almost forgetting, I'm not related in any way to Xceed Software, it's simply what I think could be a good advice.

...it doesn't necessarily mean that there's something wrong with your Xaml: it's thrown for any error during the constructor execution, even though it's caused by a C# line:

image

Technorati tags:

One of the most interesting concepts in WPF is that a control's logic is completely decoupled from its layout: a button is something that reacts when user clicks it raising a Click event, despite of how it looks like. If you think about it, it's definitely a breaking change compared to Windows Forms, and it allows designers to completely reskin UIs, while keeping the behavior intact.

When you create a new custom control, Visual Studio adds two files to your solution:

  • a C# (or VB.NET) file, which is supposed to hold all your control behavior logic
  • a Generic.xaml file, which provides a default control template for its layout.

The Generic.xaml file contains various child UI elements that need to interact with each other and with the underlying behavior logic, and this has to be done without introducing dependencies from the logic to the UI. In my experience building custom WPF control, I've been able to achieve that following three main rules:

  • Triggers (and eventually Binding between UI elements) to encapsulate layout-only logic within XAML
  • Handle data flows (both One-Way and Two-Way) from UI to control logic with Binding
  • React to UI's events using Commands

While the first two points are pretty straightforward, the third deserves a small overview. Let's suppose we're building an "File selector" custom control, similar to the following:

image

The behavior needs to be notified when the user clicks the Browse button to display the standard Windows Open File Dialog. Obviously we could assign the button a unique name

image 

and attach its click event in C# code:

image

That kind of implementation has a couple of serious drawbacks:

  • It works until there's a button named browseButton somewhere in the control template. If a designer reskins our control and doesn't provide a button with that exact name, or if he wants to use some other event, or even a different control type that doesn't inherit from button, our logic stops working correctly;
  • Our logic is so tightly bounded to the UI that we can have one and only one control triggering the opening of our open file dialog.

WPF's Commands infrastructure offer a much more elegant (and simple) solution to all those issues. A Command is the object oriented alter-ego of a functional logic, that can be enabled or disabled, triggered by an input gesture and associated to some code, regardless of what and how many UI elements are bound to it.

So, our first step is to create a proper command, stored in a static readonly field initialized into the control's static constructor. A command is a class that implements the ICommand interface; WPF has several built-in commands for the most common tasks (Cut, Copy, Past, and so on... here there's an exhaustive list). In our case, we can use the already existing RoutedCommand class:

image

Two main details to notice:

  • After building the BrowseFileCommand, you need to bind its Executed event to a proper event handler and register that binding to the CommandManager;
  • The event handler is static, but you can retrieve a reference to the current BrowseFile instance looking at the e.Source property;
  • There's absolutely no reference to any UI element in the code we've just written.

What about the general.xaml file? All we need to do is associating the BrowseFileCommand to the button object with its Command property:

image

Now, our BrowseFile behavior is well encapsulated within the C# class and its BrowseFileCommand custom command; a designer who wants to completely re-invent our control's layout only needs to attach it to the UI elements he prefers; Notice also how easy was to include a context menu with the same behavior, simply reusing the same command.

In a next post, I'll show you how to build a completly skinnable and bindable custom control from scratch.

Cheers.

kick it on DotNetKicks.com

Technorati Tags: ,,

If you need to store images at DB level, Sql Server varbinary type is what you need to hold your data, which is mapped on Linq Binary type once you import your table to a Linq project. How do you display such an image in a Image WPF control? Obviously you cannot directly bind such a data type to the Image.Source property, unless you define a proper value converter from Binary type to ImageSource type.

That said, if you want to implement one, you need to create a class that implements the IValueConverter interface. For the sake of simplicity, let's suppose that we need to support only one-way binding (Data field to Image.Source); our class might be similar to the one displayed below:

image

The logic is pretty simple: Linq's Binary type has a method which returns a byte array; what we need to do is only building a MemoryStream from it and use it to build a BitmapImage which is directly bindable to the Image.Source property.

Now, we can store our converter as a resource and use it to perform our XAML binding:

image

One last note: IValueConverter interface has a ConvertBack method too, which is needed to support two-way binding. In a next post, I'll show you how to create a two-way bindable UserControl with image upload features and we will need to implement the whole IValueConverter interface. For now, it's ok to leave it throwing a NotImplementedException.

image

Update: Here you will find the missing ConvertBack implementation

Technorati tags: , ,

Today I was preparing a demo app which integrates WPF and LinqToSql. The idea is to implement the same pattern I've always used with NHibernate: a Session DataContext per Window, automatically disposed when its owner is closed and shared among all the various UserControls it has.

So, what I did was building my custom window class with an amazing MyDatabaseDataContext property in it

   10 public class PersistentWindow : Window

   11 {

   12     private MyDatabaseDataContext myDatabaseDataContext =

   13         new MyDatabaseDataContext();

   14     public MyDatabaseDataContext MyDatabaseDataContext

   15     {

   16         get { return myDatabaseDataContext; }

   17         set { myDatabaseDataContext = value; }

   18     }

   19 }

Now, every window in my application can access the built in LINQ DataContext simply inheriting from my PersistentWindow custom class:

    1 <classes:PersistentWindow x:Class="MySampleApp.MainWindow"

    2    xmlns="http://...."

    3    xmlns:x="http://...."

    4    xmlns:classes="clr-namespace:MySampleApp.Classes"

    5    Title="Demo Application" Height="450" Width="600">

Pretty easy, isn't it? But often I do love holding a lot of logic and layout inside UserControls, both to keep my home window code simple and to build re-utilizable blocks; and almost always those UserControl need some DataBase access, that's why I need to share PersistentWindow's DataContext among all the UserControls.

If I was in Windows Forms, I probably would have ended shadowing the FindForm method with something like this:

    9 public PersistentForm FindForm()

   10 {

   11     return base.FindForm() as PersistentForm;

   12 }

But WPF has that fantastic DependencyProperty infrastructure, so maybe could be more elegant to leverage its Value Inheritance to achieve our goal. In fact, value inheritance allows property value inheritance across controls logical tree. That means that, if both your parent (window) control and your some-level child (UserControl) have the same property, the parent's property value is forwarded to every child unless they don't redefine their own value.

What we need to do is rewriting our MyDatabaseDataContext property as an AttachedProperty:

   13 public static readonly DependencyProperty MyDatabaseDataContextProperty =

   14     DependencyProperty.RegisterAttached("MyDatabaseDataContext",

   15     typeof(MyDatabaseDataContext), typeof(PersistentWindow),

   16     new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.Inherits));

   17 public static void SetMyDatabaseDataContext(

   18       UIElement instance, MyDatabaseDataContext value)

   19 {

   20     instance.SetValue(MyDatabaseDataContextProperty, value);

   21 }

   22 public static MyDatabaseDataContext GetMyDatabaseDataContext(UIElement instance)

   23 {

   24     return instance.GetValue(

   25         MyDatabaseDataContextProperty) as MyDatabaseDataContext;

   26 }

Did you notice that Inherits flag? It's what does all the magic! In fact, having a reference to window's Linq Context from our custom UserControl is simply a matter of writing a property like this:

   11 public class PersistentUserControl : UserControl

   12 {

   13     public MyDatabaseDataContext MyDatabaseDataContext

   14     {

   15         get

   16         {

   17             return this.GetValue(

   18                 PersistentWindow.MyDatabaseDataContextProperty)

   19                 as MyDatabaseDataContext;

   20         }

   21         set

   22         {

   23             this.SetValue(PersistentWindow.MyDatabaseDataContextProperty, value);

   24         }

   25     }

   26 }

Nice, isn't it?

kick it on DotNetKicks.com

Technorati tags: ,

It's 1.00 AM and, after being wondering for a couple of days about opening an English blog, I decided to install Subtext and give life to it.

Why an English blog? Well, honestly because I recently realized that I'm reading more English blogs than Italian ones, and that makes me feel as part of a .NET community that spans worldwide. I got so many visitors from abroad and I thought that the time has come for me to dive into a new challenging experience.

I'm going to talk about Software Design and Programming (which are both my everyday's bread and a great passion): some NHibernate, some WPF, some ASP.NET, some WCF and so on...! Let's see what happens!