Archive

Archive for January, 2009

Computer Graphics – Assignment 1

January 22, 2009 2 comments

I’ve long thought that Computer Graphics has been the missing piece in my Web design toolbox. It always seemed that the best designs had good graphics: even sites with very few or subtle graphics have a certain quality to them that I was never able to really replicate just using CSS and my hacked together images. I can do some basic work in a tool like Paintshop Pro, and a few years ago when I found Xara Xtreme, a real time vector graphics tool, I was able to do better. Still I wasn’t happy with my abilities: I always thought that if I wanted to move to the next level, what I really needed was some Computer Graphics training.

Now with the vector graphics orientation of WPF, Silverlight, Expression Blend, and Expression Design, and as both Designer and Developer, I truly feel that my future success in this area depends on having at least rudimentary knowledge of graphics and design principles.  Towards this end, I enrolled in Computer Graphics I at the local community college for the current semester.  I thought that since I was doing this for .Net purposes, it would be interesting to share my experiences and (hopefully) my progress.

Computer Graphics I

The class is primarily a lab class, broken down into three sections that cover three of the major design tools.  We are currently learning Adobe Illustrator.  Later we will learn Photoshop followed by a tool whose name escapes me.  I discussed Expression Design with the instructor, but he had never heard of it, so I spent some time explaining WPF and why Vector art is becoming important to Windows developers.  He seemed genuinely intrigued by the concepts so I have promised to show him some of the software.

There is a text book, which seems to cover the basic concepts such as Composition, Alignment, Grouping, etc.  I don’t consider myself very artistic, but I have to say that most of the material seems pretty intuitive.  And, while frustrating at time, Illustrator has been easy to learn because I can relate much of it to the Expression tools.  Something I have been pleasantly surprised by is that the Expression tools are better than Illustrator.  Illustrator seems to hide many of it’s features, and while it is vector oriented, most of the changes you make are not real time.  All in all, it just feels clunky to me.

Assignment: Self Portrait

For the first assignment we were to use a digital image as a base and generate a self portrait.  The purpose of the exercise was to get comfortable and familiar with Illustrator and its tooling. It was very awkward at first, but by the end of it I felt comfortable with Bezier lines for the first time ever.  Other things like Anchor points and path altering are also starting to come into focus.

Here is the original image:

The original image

The original image

And here is my artwork:

My Illustrator generated artwork

My Illustrator generated artwork

I think this turned out pretty well, all things considered.  Color matching and things like that were not part of the assignment, but I learned a lot about how to construct a graphic from many parts.  According to the instructor, Layers are not very important in Illustrator, but are very important in Photoshop.  Even so, I found the use of layering and grouping and naming parts to be invaluable even in this small project.  When he reviewed my file he said he could see a very analytical approach to design because of the way I had everything laid out and precisely named.  Personally, I don’t see how you could get by doing it differently, but maybe that’s just the developer in me coming out.

I’ll keep posting updates throughout the semester.  I’m curious to see how this will add to my total WPF skill set.

Categories: Graphics

MultiBinding in WPF

January 21, 2009 3 comments

In my current application, I have a ListBox that displays images horizontally.  Basically it is a WPF FilmStrip (without the control) with some additional features.  One feature is a toolbar that includes navigation buttons.  First and Last buttons are easy: they are always available and always navigate to the first or last image in the list.  The Previous and Next buttons are also easy to navigate, by simply incrementing or decrementing the SelectedIndex value of the ListBox.

Simple IValueConverter

While WPF seems to automatically handle numbers less than 0 and greater than the Items.Count, I only want the Previous and Next buttons enabled based on the SelectedIndex.  If the index is 0, I do not want the Previous button enabled, and if the index is the last one, I do not want the Next button enabled.  To accomplish this, I need to convert the SelectedIndex to a Boolean, so I wired up an IValueConverter.  In the case of Previous, it is a simple task in the converter to just compare the SelectedIndex to 0:

    public class SelectedItemIndexIsNotFirstToBoolean : IValueConverter
    {
        #region IValueConverter Members
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            if (value is int)
            {
                int index = (int)value;
                return (index > 0);
            }

            return false;
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }

        #endregion
    }

Basically, the converter returns True if the value is > 0 so that IsEnabled will be True.  Now to wire this up, just add the Converter to the Binding:


The XAML above does several things: first, the Path is the Property name of the Element (specified by ElementName) we want to send to the Converter. The Converter is a reference to a Resource instance of the Converter, which means you’ll have to add a line for this in Window.Resources:


If you aren’t impressed yet, think about what just happened: I bound a boolean value of a control (it could be any of them, not just IsEnabled) to the SelectedIndex value of a ListBox with no code behind or events. I don’t include the Converter classes as code behind, because I can easily see working up a DLL full of these and using them in many applications.

MultiBinding using IMultiValueConverter

The Next button, however, was not as straight forward as the Previous button.  In this case, I needed to check the SelectedIndex against the Items.Count property to see if this is the last Image in the list.  At first, I tried to use RelativeSource binding to navigate the tree and send the ListBox itself, but I quit for two reasons.  The first reason is it got hairy in a hurry I couldn’t get it to work.  The second reason is that I could see using the resulting IValueConverter for other applications and Control types, so I didn’t want to limit it.  The answer therefore became finding a way to send both the SelectedIndex and the Items.Count to a IMultiValueConverter.

A IMultiValueConverter functions much like an IValueConverter, receives an object[] as the first parameter.  Then, like the IValueConverter, we can simply process the array values and use them to determine the return value:

public class SelectedItemIndexIsNotLastToBoolean : IMultiValueConverter
{
    #region IMultiValueConverter Members

    public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (values[0] is int && values[1] is int)
        {
            int index = (int)values[0];
            int count = (int)values[1];
            return (++index != count);
        }

        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    #endregion
}

As you can see, other than processing multiple values, there is very little difference between the two.  The question then becomes “how the heck do I wire this thing up?”  If you are using Blend, I have bad news: as far as I can tell there is no way to wire up MultiBinding in Blend.  The good news is that it was really easy to do in XAML and required no RelativeSource or anything funky like that:


    
        
            
            
        
    
    

I broke the IsEnabled property out of the button and added a MultiBinding tag to it that contains all the magic.  You have to specify the Binding tags in the order the IMultiValueConverter is expecting them.  The statement is very simple, referencing the ElementName and Path as above for each value to be passed to the Converter.  I did discover something interesting: look at the second one and you’ll see I indicated “Items.Count”.  I didn’t actually think this would work since I am referencing a subproperty, but the Count came through just fine. And of course, don’t forget to add a reference to the Converter to Window.Resources.

Conclusions

There is some concern out there that too much stuff will get shoved into XAML just because we can.  The question you have to ask yourself is whether or not the time invested and the result are worth it.  In this case, I think it is justified.  Most of the time I invested here was learning the technique, which is a cost I won’t have to pay again.  It also ended in much less coding in my button Click events, and is completely reusable for different scenarios and future projects.

Categories: WPF

LiveBlogging:Microsoft PDC – Reston

January 16, 2009 Comments off

Today I am attending the Microsoft Programmer Development Conference in Reston, VA.

Keynote – Stephen Walthers

Software + Service platform is the topic. Microsoft has spent Billions developing services, sites, and data collection services.  Speaking about Windows Azure, the new Windows Operating System. Not Windows 7, but a Cloud operting system.  Built out of thousands of virtual instances of Server 2008, so that you can host applicaitons over the web.

  • Scalable hosting platform
  • Automated Service Management
  • Model-driven service lifecycle management
  • High Availability

No more reinvestment of servers and hardware, because you no longer need to build the infrastructure.  This should mean more an dbetter applications with lower cost and easier deployment.  This is called “Utility Computing”.  Azure takes advantage of existing skill sets: C#, .Net, Windows Server, Visual Studio, etc.  So for ASP.NET, you would simply publish it into the cloud.

Restriction: MS enforces programming paradigms that allow the software to scale up appropriately.

Azure is an open platform, so you can use Ruby, Python, etc.  Supports REST protocols, XML file formats, and of course Managed and native code.  It will even support unmanaged code in the future.

Users control and own their own identities.  “A single, federated identity platform” that you can take advantage of in your cloud applicatations.  But it is not mandatory, so you can still control all that information.

SQL Services – exposes SqlServer instances on the Cloud.  You can use ADO.NET Data Services, Entities, etc.  Data Sync allows you to replicate data across the cloud, and of course Sql Reporting services will be available.

Live Services – Identity, Communication and Presence, Directory, and Search and Geospatial.  Allows you to integrate with Microsoft identity, and potentially Open ID.  Opening up more directory services, so you have access to the client’s social information (like Facebook).  Geospatial is like integration of mapping etc.  Live service currently uses 11% of total Internet minutes and has over 460 million users. (Note to self: learn about MESH)  All this runs inside the Live Framework along with the Live Operating Environment and the Live Programming Model.

Online Applications – Microsoft is doing this so they can scale up to incredible numbers of users.  Now they are startin to apply this to Enterprise applications: you can push out Office, Exchange, SharePoint, CRM, etc.  Hosting these apps in house means maintaining servers, software, licenses, etc.  With Azure there is no investment in hardware, setup, deployment, etc.  Enterprise software will never completely leave the local sphere, but you can synchornize the Cloud with your local services.  Federated Identity allows you to push information from your organization to Microsoft Services Connector.  You can maintain the data at home and your customers can access it fro mthe cloud, and they stay synchronized.

The Front End Experience – Takes advantage of Silverlight, WPF, WCF, etc., and builds on the client .NET presence.

Visual Studio 2010 improvements:

  • Intellisense + jQuery
  • jQuery is a first class citizen in the .Net world – a first for an open source application
  • The Silverlight Toolkit, adds a bunch of controls (like Charting, DockPanel, TreeView, Expanders, and many more)
  • Integrated Silverlight Designer
  • ASP.NET 4.0 includes improvements to Web Forms, MVC, AJAX, and Distributed Caching (opens up the Cache APIs and includes “Velocity” a distributed cache provider)
  • VS2010 for Web Development: code focused improvements, JavaScript and AJAX tooling, Design View CSS2 support, publishing and deployment improvements

VS 2010 is being built with WPF, so I expect some serious user experience enhancements.

Windows 7 Fundamentals

  • Memory, reference sets, and graphics reduction
  • Disk I/O – registry reads and indexing reduction
  • Power reductions in DVD playback, Panel and Timers
  • Improved Spped for booting and Device readiness
  • Improved Responsiveness for things like the Start Up Menu and the Taskbar
  • Scalable to 256 processors (same Kernel as Windows Server 2008)

Windows 7 features:

  • has the ability to pin applications to the Taskbar.
  • You can also control what shows up in the Tool Tray.
  • You get application previews by hovering over the taskbar icon.
  • Jump list (which can be added to your own applications) allows you to jump to recent documents.
  • There is a new clock, you can have up to three clocks.
  • You can dock applications to the desktop.
  • You can “shake” an application and all the other windows will disappear (shake it again and they come back).
  • Library allows you to organize documents (outside of folders)  Opens document previews, and even allows cut and paste from the preview.
  • Multi-touch support for touch screens.

Developing for Windows 7:

  • Ribbon User Interface
  • Jump Lists
  • Libraries
  • Multi-touch, Ink, Speech support
  • DirectX Family
  • Pixel Shading
  • Multi-core application development
  • IDE support for very large code bases

.Net 3.5 SP1 Improvements:

  • Streamlined setup
  • Start up performance
  • Graphics improvements
  • DirectX/Direct3D Interoperability
  • More Controls
  • Built into Windows 7

Other Improvements:

  • In process side by side support
  • Managed and Native code interop
  • Dynamic Language support
  • Extensible Component model
  • Improved tooling with VS2010
  • WPF improvements – Deep Zoom, Multi-touch, VSM, Text, etc.

Conclusion – The overall theme of Microsoft’s vision is Software + Services.  Services communication, Cloud computing with Azure, etc.  Client/Server software will always be important, but connected devices are changing how we deliver the experience.  The vision is to unite all of these devices and scenarios in a unified and synchronized manner.

Categories: Miscellaneous

For all the Science Fiction Geeks

January 14, 2009 Comments off

Completely miscellaneous, but a friend of mine posted this link on Facebook, and I had to share it for any of you Science Fiction fans out there. It is a graphic of dozens of Space Ships from science fiction shows and movies, showing them in their relative sizes to one another.  Lots of fun for everyone!

Categories: Miscellaneous

Accessing Command Line Arguments in WPF

January 12, 2009 4 comments

The software I’ve been developing needs to be accessible from the command line, and in those cases it needs to be able to receive parameters in order to properly initialize the application instance.  I’d done this plenty of times in Windows Forms, but when I started looking for the public static void main entry method, I couldn’t find it.  It didn’t take long to find the answer, but I thought it was worth sharing.

Windows Forms

In Windows Forms, the way I’ve always done this is to add a string[] args parameter to Main(), which is found in “Program.cs”.  Then I override the Form constructor and pass the array to the Form.  You can also use Envorinment.GetCommandLineArgs().  That post had a couple of comments where the users seemed concerned because the first element of the array contains the full path to the executable.  If you choose this method, simply ignore index 0 and you can access the parms in exactly the same way.

WPF

The method in WPF is the same basic concept, but it occurs in a slightly different way.  Right off the bat, you’ll notice there is no “Program.cs” and no Main() method to process.  Instead, the entry for the application is found in “App.xaml.cs”.  There is no entry method here like Main: in order to process the incoming paramters, we need to add a listener to the App_Startup event.  This event will fire prior to the Window class being executed. In order to hook the event up to the application, edit “App.xaml” and add Startup=”App_Startup” to the Application declaration.

The event includes a StartupEventArgs object, which contains a reference to the Args array, so you would simply parse it as desired just like in the Windows Forms Main() method. The difference with WPF is that we do not have a call to the Window class exposed like we do in Windows Forms.  What we do have, in the Window class, is access to the Application object itself.  Microsoft’s sample, downloadable from MSDN, creates a static variable in the App class and populates it in the App_Startup event.  The Window class then accesses the static App variable for its access to the command line arguments.

The sample above parses the values and stores them in a Hashtable (yuck!), so obviously we have some better options, like a generic Dictionary.  Or even better, how about a custom class that holds the values you want?  This would be especially good if some of the values are not strings, or to enforce business rules on the incoming parameters.  I like this approach because it allows all the parsing work to be done outside the Window, leaving the Window to only determine how to use the results.  It just feels better to me since one of our primary goals with WPF is separating layers of responsibility.

If you don’t like the process above, or you really want to handle the parsing inside the Window class, you still have access to Environment.GetCommandLineArgs(), and it works exactly like it does in Windows.Forms.  Again, you can just ignore the 0 index and process the arguments directly.  Oh, and if you are a real glutton for punishment, both methods include the Environment.CommandLine property, a string that represents the complete command line entry.

Debugging Command Line Parameters

I hate trying to navigate through the DOS shell (excuse me: Command Prompt) to find the exe file of my project in order to test command line argurments.  Fortunately, we don’t have to!  If you go to the main menu and follow Projects -> “xxxApplication Properties”, and then click on the Debug tab, you’ll find a box where you can enter the Command Line Arguments you want to test.  As expected, they will be included when the application begins and you can debug their values.

Categories: WPF

Dynamically Switch WPF DataTemplate

January 9, 2009 12 comments

This post is based on this thread I started at MSDN Forums.  You can read the original situation and questions there: this post is more of a generic “how to”.

The Problem

In my original scenario I had a simple DataTemplate for ListBoxItems.  When an Item was Selected, I wanted to use a different DataTemplate that had more details.  The Binding was the same for each, so it seemed to me that I should simply be able to switch the DataTemplates at will.  Unfortunately, this is not the case.  I attempted to pull the selected item from the ListBox on the SelectionChanged event and assign it a different DataTemplate, but it did not work.  It still seems to me that it would be possible, but my efforts failed and I couldn’t find anything similar online.

The Solution

Since I couldn’t simply apply the DataTemplate resource to the SelectedItem, I had to find a different way.  After reading many suggestions for how to accomplish this, I settled on using a DataTemplateSelector.  This is a custom class with a method that returns a DataTemplate based on whatever criteria you need.  The custom DataTemplateSelector is then assigned to the element: in the case of ListBox it is the ItemTemplateSelector property.

I had previously read about DataTemplateSelector, but I was under the mistaken impression that it was used only in the context of state changes for the bound object.  This may have been because every example I found online that uses the selector approach was written with that scenario in mind.  It finally occurred to me, however, that I could access the Application state as well, which means that I could pull basically any information I needed, such as the currently selected item in my ListBox.

OK, so enough background: let’s get to how to do this.  Feel free to download the demo project for this post.

Create the Data Templates

There is nothing special about the DataTemplates themselves, so just create them as you normally would.  In the sample project, I have created a simple template and a complex template.  We’ll assign the complex template to the SelectedItem and the simple template to all the others.

Create the DataTemplateSelector

This is where the magic happens.  The code will process whenever a DataTemplateSelector instance has been assigned as well as everytime the DataSource changes.  I’ll get back to that in a minute, but for now you need to create your custom DataTemplateSelector class by extending DataTemplateSelector and overriding the SelectTemplate method:

public class PersonDataTemplateSelector : DataTemplateSelector
{
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        if (item != null && item is Person)
        {
            Person person = item as Person;
            Window window = System.Windows.Application.Current.MainWindow;
            ListBox list = window.FindName("PeopleListBox") as ListBox;

            Person selectedPerson = list.SelectedItem as Person;
            if (selectedPerson != null && selectedPerson.FullName() == person.FullName())
            {
                return window.FindResource("PeopleTemplateComplex") as DataTemplate;
            }
            else
            {
                return window.FindResource("PeopleTemplateSimple") as DataTemplate;
            }
        }

        return null;
    }
}

A few things to note:

  • the first parameter coming in is an object, so we need to test it to make sure it is the object type we expect.  Once we do that, we can then cast it to a usable instance of that type.
  • We use WPF’s knowledge of the Application to get a reference to the MainWindow where our ListBox is defined.  I then use the FindName method to get a reference to the ListBox.  This approach basically makes the entire application open to your selector instance.
  • Finally, we get a refence to the appropriate DataTemplate and return it.

So in the case of our ListBox, this method will be called for each ListBoxItem.  If no items are selected, then all of them will apply the simple template.

Assign the DataTemplateSelector

Now that we have our selector created, we need to use it in our XAML.  The first step towards this is to add a reference to our Window for the local Namespace.  I find it a good practice when I create the project to just automatically add this reference so I always have access to any local classes I may create, like ValueConverters.  Here is the line in the demo project that does this:

xmlns:prog="clr-namespace:DemoDataTemplateSelector"

Now we need to create an instance of our custom DataTemplateSelector in Window.Resources, like so:

<prog:PersonDataTemplateSelector x:Key="personDataTemplateSelector" />

Now we need to add the ItemTemplateSelector property to our ListBox and reference the object we created:

ItemTemplateSelector="{StaticResource personDataTemplateSelector}"

Finish the Code

If you run the application at this point, the simple template will be applied as selected, but the template will not change when an item is selected.  Above I said that the selector code would execute whenever the DataSource changes: selecting an item in the ListBox does not alter the DataSource, so the selector code is not activated.  The way around this is to create a new instance of the selector object and assign it programmatically to the ListBox.  In this case, we want it to execute when the SelectionChanged event fires:

private void PeopleListBox_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
    PeopleListBox.ItemTemplateSelector = new PersonDataTemplateSelector();
}

Now if you run the code it should work as desired, changing the DataTemplate from simple to complex for the selected item.

An Alternative Approach

Another approach posted here was to use a single DataTemplate containing a Trigger to switch them out.  The trick in my scenario was to figure out how to fire the trigger when the selected item changes.  I found a post at StackOverflow that demonstrated this well.  Merging these two approaches together achieved the result I wanted.  Here are a few key elements to this approach:

  • Change the original DataTemplates to ControlTemplates.
  • Create a new DataTemplate containing a single Control element that defines the default Template.
  • Add a DataTrigger that binds the RelativeSource to the Ancestor ListBox’s IsSelected property = true.
  • On the ListBox itself, instead of using the ItemTemplateSelector property, set the ItemTemplate property to the new DataTemplate.

Learning this method really opened my eyes to the power of DataTriggers.  I shied away from this at first because the XAML is more complex, and I’m still in the adolescent stages of XAML knowledge.  But having implemented it, there are definitely some benefits.  Using the DataTrigger approach requires a lot less coding: I do not have to create a custom DataTemplateSelector class; I do not need ListBox.SelectionChanged event; I do not need to declare the DataTemplateSelector instance in my XAML.  Since it can be argued that this is a purely UI problem, so keeping as much of it as possible in the XAML does a better job of separation of responsibilities.  Which means that in a scenario where designers really are separate from developers, the designer does not need to rely on the developer to achieve this feature.

Conclusion

Working through this has taken me a lot farther down the road of understanding binding, templates, and triggers.  And of course, both approaches are perfectly valid (so the sample code includes both approaches.)  I think for simple situations, triggers win hands down.  But for more complex scenarios, such as needing to base the DataTemplate selection on multiple factors, or processing more than two DataTemplates, then the custom DataTemplateSelector offers more flexibility and options.  In either case, this is one tool in my toolbox that I think I’ll be using a lot.

Categories: .NET
Follow

Get every new post delivered to your Inbox.