Over a million developers have joined DZone.

Building a WPF Application: Part 5

·

About 5pm today I was burnt-out from some difficult work on a particular client's project. Our last four projects have all been WPF with an emphasis on UI and UX. Fortunately, most of these were green field project, but the one I was working on today was not.

What made it so difficult is that the application is practically one big xaml file with all of the logic in the accompanying code behind. It's hard to modify the UI when it is so tangled up with the logic.  <sigh />

So at 5pm, I decided to take a break and work on ChumChase a bit.

Hope I'm not embarassing anyone...Here's a quick overview of what I did:

  • I began a basic 2D view that will be the actual default view for the application. The 3D view is cool, but it's a novelty and not much else. The 2D is really simple at the moment.
  • You can toggle between the 2D and 3D views. The underlying presentation model is the same. It doesn't change. The only code associate with the views is the trackball code for the 3D view.
  • I added profile pictures for the user associated with a feed entry.

Chasing Simplicity

Let's review my thinking process for adding the profile pictures.

I assumed that I could get the url for a given user's profile picture from FriendFriend's API. In fact, it is quite simple.

http://friendfeed.com/nickname/picture?size=medium

where nickname is the user you are interested in. You can provide small or large for the size as well. FriendFeed uses the term nickname where everyone else would use username.

The data template for a individual item on the feed looks like this (simplified for the post):

<DataTemplate>  
<Border>
<DockPanel>
<Grid DockPanel.Dock="Left">
<!-- this image is where the profile pick will go -->
<Image Width="50"
Height="50"
Margin="2,2,8,8" />
<Image Width="16"
Height="16"
VerticalAlignment="Bottom"
Margin="2"
Source="{Binding Path=ServiceIcon}"
HorizontalAlignment="Right" />
</Grid>

<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<TextBlock Text="{Binding Path=Title}"
TextWrapping="Wrap"
FontSize="16" />
<TextBlock Grid.Row="1"
Text="{Binding Path=User}" />
</Grid>
</DockPanel>
</Border>
</DataTemplate>

The template is bound to an instance of FeedEntry which represents a single entry in the feed. Notice the binding to User in the bottom TextBlock. That's simply the nickname of the user associate with the entry.

My first thought was to add a new property to FeedEntry called UserProfilePictureUrl and bind it to the Source property on the Image.  This new property would merely inject the value of User into a url and return it. Even though it was simple, something nagged me about this. I felt like it should not be a concern of FeedEntry to provide the url for the profile picture. In addition, I knew that I would need to get the url in other places where FeedEntry was not part of the picture.

In some sense, the translation of a nickname into a profile pic url is standalone. I mean, the concept exists independent of any of the current entities in my model. Because of this, I decided to encapsulate the concept in a value converter.

public class NicknameToProfilePicUrlConverter : IValueConverter  
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
string size = (parameter == null)
? "medium"
: parameter.ToString();

string url = string.Format("http://friendfeed.com/{0}/picture?size={1}",
value,
size);
return url;
}

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

Then in the xaml, I used the converter like this (after adding a reference in the resources):

<Image Width="50"  
Height="50"
Source="{Binding Path=User, Converter={StaticResource NicknameToProfilePicUrl}}"
Margin="2,2,8,8" />

Notice that I'm actually binding to the nickname (note to self: I should rename User to Nickname). The converter takes the nickname and returns the url. Converters like this are easy to test as well.

This implementation isn't all that robust, but we'll handle that when the need arises.

So how do you feel about having a value converter that is so specific? I find myself using them more and more. Does it bother you to take this approach?

 

Topics:

Published at DZone with permission of Christopher Bennage, DZone MVB. See the original article here.

Opinions expressed by DZone contributors are their own.

The best of DZone straight to your inbox.

SEE AN EXAMPLE
Please provide a valid email address.

Thanks for subscribing!

Awesome! Check your inbox to verify your email so you can start receiving the latest in tech news and resources.
Subscribe

{{ parent.title || parent.header.title}}

{{ parent.tldr }}

{{ parent.urlSource.name }}