Window Reuse in WPF
Really happy with some code I put together for Comicster on the weekend.
For any item in your collection, it's possible to "connect" it to Comicster's online database (hosted here at madprops.org). Once connected, you can quickly upload or download changes to synchronize that item with the online version.
To initially connect an item to the online database, of course, you need to locate the online version. You do so by searching for it using a dialog like this:
It's a pretty simple dialog, but of course the logic behind it has to change depending on what you're searching for. A search for creators (like "Stan Lee") should return a completely different set of results than a search for titles (like "Amazing Fantasy"). Not only that, the way results are displayed should change depending on what you're searching for: a search for titles should list the titles' publisher and release year, while a search for creators should list their name and web address.
I didn't want to create a different dialog for every search type, so I decided to approach the problem by passing in logic (both functional and UI logic) to the same dialog depending on what I'm searching for. Witness the dialog's constructor signature:
public OnlineSearchDialog(string searchText,
Func<string, System.Collections.IList> searchFunction,
DataTemplate resultTemplate)
{
So I'm passing some initial text to search for, and then two interesting arguments:
- A function that tells the dialog how to search, and
- A DataTemplate that tells the dialog how to display its results
This means that I can construct the dialog like this for title searches:
new OnlineSearchDialog(
title.Name,
t => _service.FindTitles(
new Online.FindTitlesMessage
{
SearchText = t,
DetailRequired = Online.TitleDetailRequired.All
}),
this.Resources["TitleSearchResultTemplate"] as DataTemplate);
and like this for creator searches:
new OnlineSearchDialog(
creator.Name,
t => _service.FindCreators(
new Online.FindCreatorsMessage
{
SearchText = t,
DetailRequired = Online.CreatorDetailRequired.None
}),
this.Resources["CreatorSearchResultTemplate"] as DataTemplate);
See what I mean? I get to pass in all the logic that's specific to the item type I'm searching for.
Passing DataTemplates around like this is not something I've thought of before now, but I feel that it's a great way to make use of the power of WPF. Have you done something like this in your own projects? Leave me a comment!