Two Different Ways to Show Enum Values in WPF

Posted by Matt | Filed under ,

For an application, I wanted to show the values from an Enum in a combo box.  While Googling, I found two different ways to do it.

  1. There’s the brute force way, shown here by Sasha Barber, and
  2. The fancier, but in the end simpler, way shown here by Andrew Smith

Extreme ListBox Customization

Posted by Matt | Filed under , ,

Just a short note that I wanted to share with all of you.  While searching on how to customize ListBox controls in WPF, I came across this post from 2007: The power of Styles and Templates in WPF.  In this article, Bea demonstrates how to make an everyday WPF ListBox control look like our solar system.  The items in the list are the planets, and she has orbit trails and everything.  Below is the results of her changes.

image 

Yes, that is a ListBox control.  Pretty amazing!

Go read her full article on how she did this.

Binding to Settings in WPF

Posted by Matt | Filed under , , ,

I just wanted to forward on a blog post that I found useful.  I was implementing a textbox whereby a user can edit an application setting.  My old way of thinking was to manually marshal the data from the setting to the control, and back again when the user clicks “Ok”.

However, this is not the “WPF Way”.

Patrick Danino explains a way to hook your text control to application settings using WPF data binding.  This produces much less code than having to marshal the data manually.

Well done Patrick!

Xaml Plugin for Adobe Illustrator

Posted by Matt | Filed under , ,

Over at Channel 9, Mike Swanson shows his plugin for Adobe Illustrator that will output the design to Xaml.  As a user of Adobe Illustrator (but not necessarily a good user), I’m going to find this plugin very useful.  I’m not a Blend user, so anytime I need graphics, I need to create them manually in Xaml.

The plugin can be downloaded here.

By the way, is it Xaml, XAML, or xaml?

A Faster Way to Include a Value Converter

Posted by Matt | Filed under , ,

Over at Ask Dr. WPF, they’ve demonstrated a way to use a value converter with less Xaml markup code.  It involves more C# code, but if you’re going to be using the value converter often in the markup, it’s a worthwhile strategy.  If you just use the converter once, then the extra C# code may not be worth the trouble.

Where Do Programmers Find Visual Designers?

Posted by Matt | Filed under , , , , ,

Have you ever created the world’s next best application, to have it be 100% bug-free, 100% intuitive, but it’s missing that nice visual appeal?  Have you created an ASP.NET web application, but you needed a web designer to give it some snazz?  Have you created a WPF or Silverlight application, but you needed a WPF designer guru, or Blend expert, to punch up the program?  Have you created an MFC application, only to need a couple more icons to go on your toolbars.

If you’ve answered ‘yes’ to any of these questions, then you’re not alone.

Larger companies can afford to have a programming team and a graphics team on their payroll.  As a start-up, entrepreneur, hobbyist, or small company, we don’t have that luxury.  Personally, I’ve experienced all of the above scenarios:  I can write code, but I cannot draw my way out of a colouring book.

So the question is:  where do programmers find visual designers?

There are some companies which can create great-looking themes for WPF. One such company is Nukeation with their Reuxables products.  This will allow you to create a non-standard looking interface, but it’s not a big change from an ordinary program.

Some companies can provide user interface consulting. Again, Nukeation can do this too.  If you have the money, this is not a bad route to take.  Here’s a case study for Frog Design that designed a very attractive business solution.

But how can a lowly programmer end up with something like this?

When Josh Smith created Podder, he initially got Grant Hinkson to design a slick user interface for him, but I think he already had a working relationship with him.  Following that, he held a contest for people to submit skins for this creation.  Not many programmers can hold contests, but it’s not a bad approach.

So I’m asking (because I really want to know):

As a programmer, what do you do when you need graphics, design, or other visual elements?

As a graphic designer, how do you find web or WPF jobs?

Does the world need a classified-type place for programmers and designers to meet and find jobs?  Will programmers find it useful to find artists?  Will graphic designers use it to find paying jobs?

Or does it already exist?

What do you think?

Data binding to more than one object

Posted by Matt | Filed under , , ,

Most UI objects in WPF have a DataContext property.  Using this property, you can have that control, or other controls data bind to the object stored in the DataContext property.  By default, this DataContext property is passed down the control hierarchy by default.  This becomes very useful when nesting controls.

However, there is only one DataContext property on any given control.  Sometimes, you may be creating a UserControl and you need to have 2 or more data bound properties.  One way to do this is to encapsulate all your data inside a single class and have an instance of that class be stored in the DataContext.  This may not be convenient though.

It’s possible to add additional property members to your UserControls that can then be data bound.  For example, we have a data class that we are going to use.

public class Data
{
    public string Name { get; set; }
    public int Age { get; set; }
}

We need to add a property member to our UserControl to store the data.

public partial class DataControl : UserControl
{
    // ...

    public Data User
    {
        get { return (Data)GetValue(UserProperty); }
        set { SetValue(UserProperty, value); }
    }

    public static readonly DependencyProperty UserProperty =
        DependencyProperty.Register("User", typeof(Data),
        typeof(DataControl), new UIPropertyMetadata());
}

Now the UserControl has a member called ‘User’ which can be referenced via data binding.  In the Xaml for the UserControl, we can do this:

<UserControl
    x:Name="Main">
    <!-- ... -->
    <TextBlock Text="{Binding User.Name, ElementName=Main}" />
    <!-- ... -->
</UserControl>

What the above does is tells the TextBlock, that the data for the Text is in an element called “Main”, which we’ve labelled our UserControl via the x:Name property, and in that element, get the data from “User.Name”.  “User” is the property on the control, “Name” is the member of the Data class that contains the user’s name which we want to put in this text box.

Had the dependency property been something like a simple string, we could have just done {Binding User, ElementName=Main}

In our main window, we’d populate the control with the data by doing the following:

<Window.Resources>
    <local:Data x:Key="User" Name="Matt" Age="33" />
</Window.Resources>
<Grid>
    <local:DataControl 
        User="{Binding Source={StaticResource User}}" />
</Grid>

Once that’s done, you can repeat as necessary to add more data members to your controls as required.  There is only one DataContext member, but you can add as many other members as you need.  It also helps towards type-safety.

My sample project can be downloaded here:  DataBindingEx.zip (9.25kb)

Mixing RichEditBox with ScrollViewer

Posted by Matt | Filed under , , ,

I was creating an application where I wanted to add a RichEditBox inside a ScrollViewer.  The window containing the ScrollViewer was resizable, so I wanted the ScrollViewer to resize.  Thusly, I wanted the RichEditBox to resize as well.

What I attempted was this:

<Window x:Class="RichTextViewScrollerView.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Title="Window1" Height="300" Width="300">
    <Grid>
        <ScrollViewer HorizontalScrollBarVisibility="Auto"
                      VerticalScrollBarVisibility="Auto">
            <RichTextBox />
        </ScrollViewer>
    </Grid>
</Window>

However, once I ran the application and started typing, I got this:

image

I tried giving a MinWidth to the RichTextBox, that helped, but it would wrap at that width:  not the full width of the window.

The problem is a bit of a chicken and an egg problem:  the ScrollViewer doesn’t have a width until it’s children have a width, and the RichTextBox doesn’t have a width until it’s parent tells it how much space it can take up.

Since I only needed to have the ScrollViewer scroll vertically, I set HorizontalScrollBarVisibility=”Disabled” and the RichTextBox worked properly.  This was because the ScrollViewer now has a defined width.

image

Tutorial: Creating a User Control in Silverlight 2.0

Posted by Matt | Filed under , , , , , ,

Project Files: SilverlightApplication1.zip (487.22 kb)

At first glance, Silverlight applications have some similarities to WPF.  In reality, Silverlight is a stripped down version of WPF. As such, there are some limitations to what you can do in Silverlight.  In the future, I hope that Microsoft will add more functionality from WPF into Silverlight.

The following tutorial is using Visual Studio 2008 and Silverlight 2.0 Beta 2.  I assume that you are not new to Visual Studio, so I won't go through every step that's not Silverlight-specific.

1.  Create a new Silverlight application.

Once the Silverlight files have been installed, you can create a new Silverlight project just like you'd create a WPF application project.

New Project

Silverlight applications must run in a web browser.  Because of this, when you create a new project, Visual Studio 2008 will ask you whether you want to create a web application for the project.

Add Silverlight Application

  In this case, I usually go with the default choice of creating a new web application to host the control.  However, you can add the new Silverlight application into an existing project if that is what you require.  In the end, moving the Silverlight application from one project to another is quite easy:  you just need to modify some HTML.  Below is my project newly created in Visual Studio 2008.

New Project

2.  Create a new Silverlight User Control

Add to your project a new Silverlight User Control.

Add User Control

A user control is not a fully custom control: it is a control which groups/displays existing controls in a reusable collection.  This is useful if you want to create a "dialog" to display to the user.  You can create a user control which represents the dialog and place the controls (text boxes, buttons, checkboxes, etc.) on the user control that you need.

We are going to place a button and a text box on our control and link them together.  First, you need to edit your user control's Xaml file.

<UserControl x:Class="SilverlightApplication1.SilverlightControl1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <Grid x:Name="LayoutRoot" Background="White"
          HorizontalAlignment="Center">
        <StackPanel Orientation="Horizontal">
            <TextBox Width="200" Height="30" />
            <Button Content="Push Me" Width="100" Height="50"/>
        </StackPanel>
    </Grid>
</UserControl>

What I changed from the default user control generated:

  1. I added a StackPanel, which has a Horizontal orientation
  2. To the StackPanel, I added a TextBox and a Button
  3. I made the grid centre-aligned
  4. I removed the width and height from the UserControl itself so that it will "fit" around the controls.

My control looks like this in the Visual Studio 2008 visualizer:

User Control

3.  Place the new control on your page

Placing your control on your page is a 2 step process:

  1. Add the namespace for your control to your page.  This is done by adding the following attribute to your page's Xaml:
    xmlns:local="clr-namespace:SilverlightApplication1"
    Visual Studio's IntelliSense helps you out a bit with this one.
  2. Insert the control into your page's grid:
    <Grid x:Name="LayoutRoot" Background="White">
        <local:SilverlightControl1 />
    </Grid>

My page's Xaml looks like this:

<UserControl x:Class="SilverlightApplication1.Page"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:SilverlightApplication1"
    Width="400" Height="300">
    <Grid x:Name="LayoutRoot" Background="White">
        <local:SilverlightControl1 />
    </Grid>
</UserControl>

and the visualizer shows:

Page View

 

If we compile and run the application now, we'll get the text box and button in our browser.  However, they don't do much.

First Version

4.  Do something when the user clicks the button

I want the text box data to convert to uppercase when I click the button.  There are a couple of ways to do this.  It can be done with data binding, but I'm going to do it with C# code.

In order to access the text box, we must give it a name:

<TextBox Width="200" Height="30" x:Name="MyText"/>

On my user control, if I start typing "Click=" in my button, Visual Studio 2008 IntelliSense will prompt me to create a new event handler.

Add Handler

The Xaml looks like this:

<Button Content="Push Me" Width="100" Height="50"
    Click="Button_Click"/>

and a new function was created in the C# code:

private void Button_Click(object sender, RoutedEventArgs e)
{

}

Just like in a WPF application, or a Windows Forms application, we just need to add code to this function to perform the actions for when the user clicks the button.

private void Button_Click(object sender, RoutedEventArgs e)
{
    string sText = MyText.Text;
    sText = sText.ToUpper();
    MyText.Text = sText;
}

Notice that we are accessing the text box data by the name that we gave the text box in the Xaml code.

Now, when we run this in the browser, we get:

Input

and clicking "Push Me" will produce:

Result

There you have it.  You now have a custom User Control that pretty much does nothing useful.  But the steps here should give you an idea of what's needed to customize your own user control for your Silverlight application.

In an upcoming tutorial, I will go through creating a "true" custom control (or in-as-much as you can with Silverlight 2.0).

Features Missing from Silverlight 2 Beta 2

Posted by Matt | Filed under , , ,

I have been playing with Silverlight 2 Beta 2.  I've always liked creating WPF applications (even if the UI performance is poor), but being able to create the same applications in a browser environment is pretty cool.

However, there are some fundamentals needed to create really good GUI applications under Silverlight:

  1. Ability to derive directly from FrameworkElement and overloading MeasureOverride(), ArrangeOverride(), GetVisualChild(), and VisualChildCount are necessary
  2. Ability to draw directly to a DrawingContext are necessary

These are 2 features which are fundamental to creating a full graphics editor.

Because of #1, all custom controls must be derived from other custom controls.  If you want a custom container, it must be derived from Canvas, etc.  Even if your control is not a container in the traditional sense of the word, it needs to be a container if you want to do any custom drawing, because you cannot just draw, you must create child geometry controls which must be contained within your non-container control.

Because of #2, you have to keep a map between your data objects and your on-screen graphical objects.  Doable, but it's going through hoops to accomplish something simple in a desktop application.