Archive for the 'CSharp' Category

Consuming RESTful Web Services in WPF

It turns out that consuming the RESTful web service created in my last post is very simple when WPF’s XML data binding features are used. I have previously posted about binding to XML data in a WPF application.

My RESTful web service uses XML namespaces in its return data, so I first declare an XmlNamespaceMappingCollection in my WPF application XAML. Next I declare an XmlDataProvider for the composer list and set its Source property to the URI of my Composers RESTful operation. A second XmlDataProvider is declared for the composition data, but that is still empty at this time.

<Window.Resources>
    <XmlNamespaceMappingCollection x:Key="NamespaceMapping">
        <XmlNamespaceMapping Uri="https://patconroy.wordpress.com/data" Prefix="pc" />
    </XmlNamespaceMappingCollection>
    <XmlDataProvider x:Key="ComposerData" 
                     XmlNamespaceManager="{StaticResource NamespaceMapping}"
                     Source="http://localhost:8000/service/restbaroque/composers"/>
    <XmlDataProvider x:Key="CompositionData"
                     XmlNamespaceManager="{StaticResource NamespaceMapping}"/>
</Window.Resources>

A ListBox created on the main Window that binds to the ComposerData XML source. Note that the StringFormat property used on the MultiBinding here was introduced in the 3.5 SP1 version of the framework. It is not available in earlier versions.

<ListBox x:Name="_composerList" Margin="40,20" 
                 ItemsSource="{Binding Source={StaticResource ComposerData}, XPath=//pc:Composers/pc:Composer}">
    <ListBox.ItemTemplate>
        <DataTemplate>
            <TextBlock>
                <TextBlock.Text>
                    <MultiBinding StringFormat="{}{0} {1} {2}">
                        <Binding XPath="pc:FirstName"/>
                        <Binding XPath="pc:MiddleName"/>
                        <Binding XPath="pc:LastName"/>
                    </MultiBinding>
                </TextBlock.Text>
            </TextBlock>
        </DataTemplate>
    </ListBox.ItemTemplate>
</ListBox>

That’s all the work the needs to be done to display the composer list. A Click event handler for a button on the Window sets the appropriate Source for the compositions XmlDataSource.

private void Button_Click(object sender, RoutedEventArgs e)
{
    if (_composerList.SelectedItem == null)
    {
        MessageBox.Show("Please select a composer");
    }
    else
    {
        XmlNamespaceManager ns = Resources["NamespaceMapping"] as XmlNamespaceManager;
        XmlNode node = _composerList.SelectedItem as XmlNode;
        string id = node.SelectSingleNode("pc:Id", ns).InnerText;
        string uriString = String.Format("http://localhost:8000/service/restbaroque/composers/{0}/compositions", id);
        Uri uri = new Uri(uriString);
        XmlDataProvider dp = Resources["CompositionData"] as XmlDataProvider;
        dp.Source = uri;
    }
}
 

A second ListBox on the Window binds to the compositions XmlDataProvider.

<ListBox x:Name="_compositionList" Margin="40,20" 
         ItemsSource="{Binding Source={StaticResource CompositionData}, XPath=//pc:Compositions/pc:Composition}"/>

That’s it!
restfulclient

RESTful Web Service in WCF

The RPC-based services presented thus far on this blog have used standard SOAP and WS-* encodings over an HTTP transport. This is evidenced by the wsHttpBinding binding in the service configuration. RPC is a traditional client/server architecture whereby the client calls a command or action on the service. The World Wide Web is constructed around a different architecture where clients request resources from a service. Resources are identified by Uniform Resource Identifiers (URI) and often contain links to other resources. This architecture is known as Representational State Transfer or REST. Consult the Wikipedia article on REST for more details.

Web services can also be constructed using the REST architecture. Such services are called RESTful. Resources on the Web are returned to your browser as, for example, HTML documents and JPEG images, are presentation oriented, and are intended to be rendered in human-readable form. RESTful services, on the other hand, return machine-readable resources as XML documents or in JSON format.

RESTful services can be created quite easily in WCF using the .NET framework 3.5. In fact configuration is much easier than with SOAP services. Here I will make the Baroque composer service that I created in my last postRESTful. First declare the service contract.

[ServiceContract(Namespace="https://patconroy.wordpress.com/service")]
public interface IRestBaroque
{
    [OperationContract]
    [WebGet(UriTemplate = "/composers")]
    ComposerCollection GetComposers();

    [OperationContract]
    [WebGet(UriTemplate = "/composers/{composerId}")]
    Composer GetComposer(string composerId);

    [OperationContract]
    [WebGet(UriTemplate = "/composers/{composerId}/compositions")]
    CompositionCollection GetCompositions(string composerId);

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/json/composers")]
    ComposerCollection GetComposersJson();

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/json/composers/{composerId}")]
    Composer GetComposerJson(string composerId);

    [OperationContract]
    [WebGet(ResponseFormat = WebMessageFormat.Json, UriTemplate = "/json/composers/{composerId}/compositions")]
    CompositionCollection GetCompositionsJson(string composerId);
}

Notice the additional attribute WebGet attached to each operation. This informs the framework that following operation is to be invoked on when an HTTP GET method is received for a certain resource. The WebGetAttribute.UriTemplate property identifies the URI of the resource that the service operation will respond to. UriTemplate is, as its name implies, a template that may contain runtime replaceable parameters. The framework parses these parameters from the requested URI at runtime and passes them in to the operation implementation as method parameters. The name in the template must match exactly the parameter name in the operation method. Additionally, the method parameter must be of type string. The framework will not convert from string to any other data type such as int. That must be done in the operation implementation, as it is in this example.

public CompositionCollection GetCompositions(string composerId)
{
    CompositionCollection compositions = null;
    int id;
    if (Int32.TryParse(composerId, out id))
    {
        compositions = GetCompositionData(id);
    }

    if (compositions == null || compositions.Count == 0)
    {
        WebOperationContext.Current.OutgoingResponse.SetStatusAsNotFound();
        return null;
    }
    return compositions;
}

Also notice how an error condition is handled. The HTTP status is set to an appropriate value, in this case 404 or “Not Found”, when an invalid composer ID is passed in. A RESTful service should utilize HTTP to its fullest extent in a manner that follows the HTTP protocol standard.

I have already mentioned that configuration of a RESTful service is much easier than a SOAP service in WCF. This is the only bootstrap code needed to self-host this service. There is no <system.serviceModel> section in the application configuration file. WebServiceHost’s default settings take care of most common scenarios. Simplified configuration is also available in IIS hosted scenarios using WebServiceHostFactory.

public static void Main()
{
    Uri uri = new Uri("http://localhost:8000/service/restbaroque");
    using (WebServiceHost serviceHost = new WebServiceHost(typeof(BaroqueService), uri))
    {
        serviceHost.Open();

        // The service can now be accessed.
        Console.WriteLine("The service is ready.");
        Console.WriteLine("Press <ENTER> to terminate service.");
        Console.WriteLine();
        Console.ReadLine();
     }
}

RESTful service GET methods can be tested simply by using a browser. I simply enter the URL http://localhost:8000/service/restbaroque/composers into the IE address bar after starting the service. The result is an XML document listing all of the composers in my test database, just as I expected.
rest_composers

I could have gotten the same data in JSON format using the URL http://localhost:8000/service/restbaroque/json/composers. This would be useful if I was creating an AJAX client that consumed this service. The WebGetAttribute applied to the service operation GetComposersJson specifies an UriTemplate of “/json/composers” and sets the ResponseFormat property to WebMessageFormat.Json.

In the future I will enhance the service with add, update and delete methods. I will also create a WPF client to consume this service. Stay tuned.

Asynchronous Web Service Implementation

In my last post I demonstrated different ways to invoke a web service asynchronously in a WPF smart client application. It’s also possible to implement the service itself using the asynchronous pattern.

For this example I will create a Baroque service. The contract for this service contains two operations: GetComposers and GetCompositions. GetComposers returns a list of Baroque era music composers via an array of Composer types. Composer is declared as a data contract that contains members for a unique numeric id, first, middle and last names.

GetCompositions returns a collection of well known compositions of a given composer. It takes the composer’s numeric id as a parameter and returns an array of string. The service contract would normally be declared as follows for a synchronous implementation.

[ServiceContract(Namespace = "https://patconroy.wordpress.com/service")]
public interface IBaroque
{
    [OperationContract]
    Composer[] GetComposers();

    [OperationContract]
    string[] GetCompositions(int composerId);
}

I’ll demonstrate later that this is how the client will see the service contract, but it must be declared differently on the back-end for asynchronous operation.

[ServiceContract(Namespace="https://patconroy.wordpress.com/service")]
public interface IBaroque
{
    [OperationContract(AsyncPattern=true)]
    IAsyncResult BeginGetComposers(AsyncCallback callback, object asyncState);
    Composer[] EndGetComposers(IAsyncResult result);

    [OperationContract(AsyncPattern=true)]
    IAsyncResult BeginGetCompositions(int composerId, AsyncCallback callback, object asyncState);
    string[] EndGetCompositions(IAsyncResult result);
}

First of all each operation is now implemented as a pair of Begin/End methods and some additional parameters were introduced. This follows the standard .NET asynchronous pattern, so it should look familiar. Additionally the AsyncPattern property of the OperationContract attribute must be set to true.

Since I’m implementing the async pattern rather than just using it I created a helper class that implements the IAsyncResult interface. This will be returned by the two Begin methods and will subsequently be passed back to the End methods. This class can hold and application state data that’s needed between the Begin and End calls. The class also includes a ManualResetEvent that gets set when the asynchronous operation completes

public class AsyncResult : IAsyncResult
{
    private object _state;
    private AsyncCallback _callback;
    private ManualResetEvent _event;

    public AsyncResult(AsyncCallback callback, object state)
    {
        _callback = callback;
        _state = state;
        _event = new ManualResetEvent(false);
    }

    #region IAsyncResult Members
    public object AsyncState
    {
        get { return _state; }
    }

    public WaitHandle AsyncWaitHandle
    {
        get { return _event; }
    }

    public bool CompletedSynchronously
    {
        get { return false; }
    }

    public bool IsCompleted
    {
        get { return _event.WaitOne(0, false); }
    }
    #endregion

    public void Complete()
    {
        _event.Set();
        if (_callback != null)
            _callback(this);
    }
}

To implement this solution I created and Access database named baroque.mdb that has two tables: Composer and Composition. Composer has a unique id column as well as the first, middle and last name text columns. Composition has the composer id and composition name columns. As you might guess there is a one-to-many relationship between composer and composition. This example used the OLE-DB data provider to read the table.

public IAsyncResult BeginGetComposers(AsyncCallback callback, object asyncState)
{
    TypedAsyncResult<Composer&#91;&#93;> result = new TypedAsyncResult<Composer&#91;&#93;>(callback, asyncState);
    ThreadPool.QueueUserWorkItem(new WaitCallback(GetComposers), result);
    return result;
}

public Composer[] EndGetComposers(IAsyncResult result)
{
    TypedAsyncResult<Composer&#91;&#93;> asyncResult = result as TypedAsyncResult<Composer&#91;&#93;>;
    if (result != null)
    {
        asyncResult.AsyncWaitHandle.WaitOne();
        return asyncResult.Result;
    }
    return null;
}

As you can, see the Begin operation sends the work to a background thread. GetComposers isn’t listed here but it’s in the code download. The framework calls the End method. You don’t do that at all. TypedAsyncResult is a specialization of AsyncResult that stores a generic operation result. It’s in the code download. BeginGetCompositions and EndGetCompositions are implemented similarly.

What is the benefit of the extra coding that was done here? For this example there really isn’t one. The OLE-DB data provider only supports synchronous database operations, so I had to create my own background thread. The SQL Server data provider, on the other hand, does support asynchronous operations. Had I used SQL Server instead of Access then I would have used SqlCommand.BeginExecuteReader and SqlCommand.EndExecuteReader. Background threading is handled in the framework rather than in the application.

WCF hides all of these implementation details from the client. The client only sees GetComposers and GetCompositions methods as if they were synchronous implementations. Of course the WCF client proxy can optionally contain the methods needed to call the service asynchronously. I described these in my last post. These are, however, independent of the server implementation. The client can choose to call the service synchronously or asynchronously regardless of how the service was coded. The code download contains a WPF client application that uses the event based asynchronous pattern to call the service.

composerclient

All of the source code from this post can be downloaded here.

Asynchronous Web Service Invocation

In my last post I described various ways to perform work on a background thread in a WPF smart client application. Performing long running operations on the main application thread will freeze the user interface and yield a poor user experience. On the other hand any GUI elements must be manipulated on the main application thread and only on that thread. In this post I describe three different ways to make web service calls on a background thread using WCF client components.

First I created a simple, self-hosted WCF service implementing a simple calculator interface. The Windows SDK has several example implementations of this interface. Each of the implementation methods in my service sleeps for 10 seconds to simulate a long running process.

[ServiceContract(Namespace="https://patconroy.wordpress.com/service")]
public interface ICalculator
{
    [OperationContract]
    double Add(double n1, double n2);
    [OperationContract]
    double Subtract(double n1, double n2);
    [OperationContract]
    double Multiply(double n1, double n2);
    [OperationContract]
    double Divide(double n1, double n2);
}

Those of you running Vista will need to execute the following command as administrator to update the system URL ACL, substituting your own Windows domain and userid in the appropriate place.

netsh http add urlacl url=http://+:8000/ user=domain\userid

The client application example presents four different ways of calling the web service. The main windows has four radio buttons to select from amongst them.

  1. Synchronously on the GUI thread
  2. Asynchronously using BackgroundWorker
  3. Using the Asynchronous Programming Model
  4. Using a new .NET 3.5 event based model

The first of these is certainly the easiest to code. All work occurs on the main application thread, but herein lies a problem. The user interface is frozen while the application waits for the web service to return.

Using BackgroundWorker

The second technique is certainly an improvement. BackgroundWorker is used to launch a background thread that makes the web service call. The background thread waits for the web service to return then sets DoWorkEventArgs.Result. This Result is handed to the RunWorkerCompleted delegate on the GUI thread.

private static void CallServiceBackgroundWorker(Window1 win, double n1, double n2)
{
    BackgroundWorker bw = new BackgroundWorker();
    bw.DoWork += BackgroundWorker_DoWork;
    bw.RunWorkerCompleted += win.BackgroundWorker_RunWorkerCompleted;
    bw.RunWorkerAsync(win);
}
// BackgroundWorker callbacks
static void BackgroundWorker_DoWork(object sender, DoWorkEventArgs e)
{
    Window1 win = (e.Argument) as Window1;
    e.Result = _calcClient.Add(win._data.Number1, win._data.Number2);
}
void BackgroundWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    // This callback is made on the GUI thread
    UpdateResult((double)e.Result);
}

Do you see a problem here? Earlier I stated that “The background thread waits for the web service.” The application consumes a background thread while waiting for the web service to finish. This background thread could be utilized for something else while the web service call is outstanding. This isn’t a problem in a small example but could be a scalability killer in a larger real-world application.

Using the Asynchronous Programming Model

This last problem is solved by the Asynchronous Programming Model. The APM pervades the .NET framework. One can, for example, read a FileStream using this method. It works roughly like this.

void CallServiceAsyncPattern(Window1 win, double n1, double n2)
{
    IAsyncResult ar = obj.BeginXyz(param, new AsyncCallback(MyCallback), state);
}
void MyCallback(IAsyncResult ar)
{
    var result = obj.EndXyz(ar);
}

The names of the Begin and End methods will of course differ from class to class. The main application thread initiates the asynchronous operation by calling BeginXyz(). The framework itself then performs the operation on a background thread or better yet by using overlapped I/O. Overlapped I/O is a Windows OS feature that completes the I/O operation in the Windows kernel. An application callback is called when the operation completes. The callback occurs on a background thread.

The .NET web service proxy generator creates a Begin and End method for each of the service interface methods when the /async command line option is specified.

svcutil http://localhost:8000/service/calculator/mex /async

Or just check “Generate asynchronous operations” when creating a service reference in Visual Studio. This example client uses BeginAdd and EndAdd. AsyncCallback is called on a background thread when the web service operation completes. AsyncCallback cannot access the GUI directly, so it dispatches the result to the GUI thread.

private delegate void UpdateResultDelegate(double n);
private static void AsyncCallback(IAsyncResult ar)
{
    double result = _calcClient.EndAdd(ar);
    Window1 win = (ar.AsyncState as Window1);
    // Result must be dispatched to the GUI thread
    win.Dispatcher.Invoke(new UpdateResultDelegate(win.UpdateResult), result);
}
private static void CallServiceAsyncPattern(Window1 win, double n1, double n2)
{
    IAsyncResult ar = _calcClient.BeginAdd(n1, n2, AsyncCallback, win);
}

Using an event based model

A new event based asynchronous model was introduced in the framework version 3.5. The service proxy generator creates all the necessary delegate declarations and event argument classes. It also adds a completed event and an XyzAsync() method to the proxy class for each of the web service methods. Specify /tcv:version35 in addition to /async on the svcutil command line to generate this additional code. This is also done automatically in Visual Studio when “Generate asynchronous operations” is checked.

The event model is an improvement over APM because the completed event is called on the same thread that initially made the asynchronous service request. In the example here AddAsync() is called on the GUI thread, so the AddCompleted event handler is called on the GUI thread after the web service returns. The need to dispatch the result to the GUI thread has been eliminated. GUI state can be manipulated within the event handler, so coding is much easier than with APM.

Event handlers must be set on the service proxy instance prior to making any service requests. This example only uses the Add service method, so only an AddCompleted event handler is set. CalculatorClient also includes SubtractCompleted, MultiplyCompleted and DivideCompleted event handlers.

private static CalculatorClient _calcClient;
static Window1()
{
    _calcClient = new CalculatorClient();
    _calcClient.AddCompleted +=new EventHandler<AddCompletedEventArgs>(CalcClient_AddCompleted);
}
private static void CalcClient_AddCompleted(object sender, AddCompletedEventArgs e)
{
    // This callback is made on the GUI thread
    (e.UserState as Window1).UpdateResult(e.Result);
}

Initiating an asynchronous call to Add is simply a matter of calling CalculatorClient.AddAsync(). Note that the code generator also created SubtractAsync, MultiplyAsync and DivideAsync methods.

private static void CallServiceNewAsync(Window1 win, double n1, double n2)
{
   _calcClient.AddAsync(n1, n2, win);
}

All source code for this example is located here.

Background Threads in WPF

Anyone writing smart client applications will eventually run into a situation where some work must be performed asynchronously on a background thread. Long running computations, database access, web service calls and large file I/O are all good candidates. Any long-running operation must be performed on a background thread to avoid freezing the user interface. More often than not the UI state needs to change after the background operation completes. Perhaps the UI must show feedback as the operation executes – think progress bar. It would be great to update the UI right from the background thread, but WPF has strict rules concerning threading.

There’s one rule really, but it’s important and will drive how you design the background thread to UI conversation. WPF UI elements must be manipulated only on the UI thread. This rule pertains to instances of any class that inherits directly or indirectly from DispatcherObject, and this means all UI elements.

So you can’t set TextBox.Text or TreeViewItem.Header from any but the UI thread, is that it? Well, not exactly. Data binding complicates things. I’ve created a sample program where a ListBox is bound to an ObservableCollection. With this binding in place any changes to the collection indirectly manipulate the ListBox. Recall that ObservableCollection raises the CollectionChanged event whenever the items list changes. The ListBox, or more accurately a CollectionView that the framework inserts between the ListBox and bound collection, handles his event. CollectionChanged is raised synchronously on whatever thread modified the collection. When performed on any other than the UI thread a NotSupportedException is raised. You can see this in action by clicking on the button labeled “Kaboom!” in the sample program.

wpfthreads

Here’s the code that executes when “Kaboom!” is clicked.

private void Kaboom_Click(object sender, RoutedEventArgs e)
{
    ThreadPool.QueueUserWorkItem(new WaitCallback(KaboomThreadProc), this);
}
static void KaboomThreadProc(object sender)
{
    Window1 win = sender as Window1;
    string item = GetNextItem();
    // Sleep to simulate a long running process
    Thread.Sleep(1000);
    win.AddItem(item);
}

WPF provides the Dispatcher class to route work back to the UI thread. A Dispatcher object is created on the UI thread when the application starts up. Work can be sent to the UI thread by using this Dispatcher object and it’s Invoke or BeginInvoke methods. Invoke executes the work synchronously while BeginInvoke is asynchronous. This Dispatcher object is accessed in several ways. The static Dispatcher.CurrentDispatcher property will return it when called on the UI thread. Every DispatcherObject keeps a reference to the Dispatcher from the thread on which it was created. In other words every UI element has a Dispatcher property that returns the UI thread’s Dispatcher object. The current example used the Window’s Dispatcher in order to update the ObservableCollection on the UI thread. Click the button labeled “Dispatcher” to execute this code which updated the ListBox successfully.

private delegate void AddItemDelegate(string item);
private void AddItem(string item)
{
    _coll.Add(item);
}
 static void DispatcherThreadProc(object sender)
{
    Window1 win = sender as Window1;
    string item = GetNextItem();
    // Sleep to simulate a long running process
    Thread.Sleep(1000);
    win.Dispatcher.Invoke(DispatcherPriority.Normal,
        new AddItemDelegate(win.AddItem), 
        item);
}

Note that Dispatcher is a priority based queue of work items that get executed as the thread’s message pump processes Windows messages. Here the sample invokes a delegate on the UI thread at Normal priority, but other higher or lower priorities could have been used.

BackgroundWorker, a holdover from Windows Forms, may also be used as it fires its RunWorkerCompleted event on the UI thread. Perform some background work in the DoWorkEventHandler delegate. The DoWorkEventArgs parameter that the delegate receives contains Result property that should be set to the result of the background operation. The Result is passed to the RunWorkerCompletedEventHandler delegate so that it may be used on the UI thread to update the UI state. Click the button labeled “BG Worker” to update the ListBox using this method.

private void BGWorker_Click(object sender, RoutedEventArgs e)
{
    BackgroundWorker bgWorker = new BackgroundWorker();
    bgWorker.DoWork += new DoWorkEventHandler(BGWorker_DoWork);
    bgWorker.RunWorkerCompleted += new RunWorkerCompletedEventHandler(BGWorker_RunWorkerCompleted);
    bgWorker.RunWorkerAsync(this);
}
static void BGWorker_DoWork(object sender, DoWorkEventArgs e)
{
    string item = GetNextItem();
    // Sleep to simulate a long running process
    Thread.Sleep(1000);
    e.Result = item;
}
void BGWorker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
{
    AddItem(e.Result as string);
}

Source code for this sample may be downloaded here.

XML Data Binding in WPF

Data binding is a powerful and time saving feature of the WPF framework. It allows a depencency property in the application’s view layer, such as a TextBox’s Text property, to be bound to a property in the application’s underlying data model. Data model in this instance means .NET classes or, as I’ll show later, an XML document. Data binding saves us from the tedious task of writing code to move data to and from WPF controls on the screen.

In my last two posts about styling the ListView I bound a ListView control to an underlying collection of type ObservableCollection<string>. Most real-world applications will bind ItemsControls to a collection of objects more complex than string. The screen controls then access properties of the underlying objects using data binding. More visually complex representations can be created by using data templates.

The XmlDataProvider in conjunction with the Binding class enable binding to elements and attributes in an XML DOM using XPath expressions. XmlDataProvider can load an XML document from a local system disk, from a remote system, or, as the example here does, from an XML data island in the application itself. XmlDataProviders can be easily created in a resource dictionary using XAML.

<Application.Resources>
    <XmlDataProvider x:Key="Xml1" Source="c:\documents\xml\automobiles.xml"/>
    <XmlDataProvider x:Key="Xml2" Source="http://www.somecompany.com/finance/Q3results.xml"/>

The sample application here displays various facts about the states of the United States of America. The data is limited to the first 13 states as all 50 aren’t needed for the example. They are listed in the order that they ratified the Constitution for the United States of America. The XML schema for the document is listed below.

<?xml version="1.0" encoding="utf-8"?>
<xs:schema xmlns:xs="http://www.w3.org/2001/XMLSchema">
  <xs:complexType name="StateType">
    <xs:all>
      <xs:element name="Capital" type="xs:string" />
      <xs:element name="Nickname" type="xs:string" />
      <xs:element name="Bird" type="xs:string" />
      <xs:element name="Flower" type="xs:string" />
      <xs:element name="Tree" type="xs:string" />
      <xs:element name="Motto" type="xs:string" />
    </xs:all>
    <xs:attribute name="Name" type="xs:string" use="required" />
    <xs:attribute name="Abbrev" type="xs:string" use="required" />
  </xs:complexType>
  <xs:complexType name="StatesType">
    <xs:sequence maxOccurs="unbounded">
      <xs:element name="State" type="StateType" />
    </xs:sequence>
  </xs:complexType>
  <xs:element name="States" type="StatesType" />
</xs:schema>

The XmlDataProvider containing the XML document itself is created in the application resource dictionary. Note that the data island is contained within an <x:XData> element.

<XmlDataProvider x:Key="StateData">
    <x:XData>
        <States xmlns="">
            <State Name="Delaware" Abbrev="DE">
                <Capital>Dover</Capital>
                <Nickname>The First State</Nickname>
                <Bird>Blue Hen Chicken</Bird>
                <Flower>Peach Blossom</Flower>
                <Tree>American Holly</Tree>
                <Motto>Liberty and Independence</Motto>
            </State>
            <!-- Remaining states omitted for brevity -->
        </States>
    </x:XData>
</XmlDataProvider>

The application window consists of two panes. The left-hand pane contains a ListBox that lists the states from the XML document. This isn’t a simple list of state names. A DataTemplate is used to display an image of the state’s flag along with its name. The GIF images of the state flags used in this example were provided by the kind folks at 3DFlags.com.

xmldata

The DataTemplate is created in the application resource dictionary. See the XAML source below. Note that a value converter is used to construct the name of the flag image file. The GIF images are included in the Visual Studio project in a folder named Images.

<local:ImageNameConverter x:Key="ImageNameConverter"/>
<DataTemplate x:Key="StateListTemplate">
    <StackPanel Orientation="Horizontal">
        <Image Width="64" Source="{Binding XPath=@Abbrev,Converter={StaticResource ImageNameConverter}}"/>
        <TextBlock Margin="6,12,0,0" Text="{Binding XPath=@Name}" FontSize="14"/>
    </StackPanel>
</DataTemplate>

Here’s the source for the value converter.

class ImageNameConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        if (value is string)
        {
            return @"Images\" + (value as string) + ".gif";
        }
        else
        {
            throw new ArgumentException();
        }
    }

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

In the main Window I establish the data source for the window by binding to the XmlDataSource. An XPath expression is used to access the collection of <State> elements in the document.

<Window x:Class="XMLData.Window1"
    DataContext="{Binding Source={StaticResource StateData},XPath=//States/State}">
</Window>

The ListBox ItemTemplate property references the DataTemplate shown earlier.

<ListBox x:Name="_stateList" Grid.Column="0" Margin="2,2,6,2" 
         Background="Beige"
         ItemsSource="{Binding}" ItemTemplate="{StaticResource StateListTemplate}"
         IsSynchronizedWithCurrentItem="True"/>

The rest of the application references the ListBox’s SelectedItem. For example the status bar displays the name of the state currently selected in the ListBox. I did this by binding the Text property of a TextBlock to the SelectedItem property of the ListBox. A value converter is used once again to get the desired text.

<StatusBarItem>
    <TextBlock Text="{Binding ElementName=_stateList,Path=SelectedItem,Converter={StaticResource SelectedItemConverter}}"/>
</StatusBarItem>

The right-hand pane of the application displays far more information than just the state name. A FlowDocumentScrollViewer is used to display a FlowDocument that contains the relevant information. Within the FlowDocument instances of TextBlock have their Text properties bound to various elements within the currently selected <State> element. Again, XPath expressions are used to obtain the desired data. By using data binding I avoid writing any C# code whatsoever to update the details pane when a new state is selected in the list box. The WPF binding framework handles this automatically. In fact there is very little code behind in this application at all. All data movement is handled through binding. I only created two value converters to coerce some of the data into a more displayable form.

<FlowDocumentScrollViewer Grid.Column="1" Margin="2">
    <FlowDocument Background="Beige" DataContext="{Binding ElementName=_stateList,Path=SelectedItem}">
        <Paragraph FontSize="16" FontStyle="Italic" FontWeight="Bold" TextAlignment="Center">
            <TextBlock Text="{Binding XPath=@Abbrev}"/>
            <Run Text=" - "/>
            <TextBlock Text="{Binding XPath=@Name}"/>
        </Paragraph>
        <Table FontSize="12" CellSpacing="8">
            <Table.Columns>
                <TableColumn Width="Auto"/>
                <TableColumn/>
            </Table.Columns>
            <TableRowGroup>
                <TableRow>
                    <TableCell><Paragraph>Capital</Paragraph></TableCell>
                    <TableCell>
                        <Paragraph>
                            <TextBlock Text="{Binding XPath=Capital}"/>
                        </Paragraph>
                    </TableCell>
                </TableRow>
                <!-- Other rows omitted for brevity -->
            </TableRowGroup>
        </Table>
    </FlowDocument>
</FlowDocumentScrollViewer>

All source code may be downloaded here.

Alternating row background color in WPF ListView

In yesterday’s post you’ll notice that the ListView control displays using different colors for alternating rows. I implemented this effect by using a style selector. A style selector is basically a class that inherits from StyleSelector and overrides the SelectStyle method. Here’s my implementation.

public class ListViewItemStyleSelector : StyleSelector
{
    public override Style SelectStyle(object item, DependencyObject container)
    {
        ListView listView = ItemsControl.ItemsControlFromItemContainer(container) as ListView;

        Style st;
        int index = listView.ItemContainerGenerator.IndexFromContainer(container);
        if (index % 2 == 0)
        {
            st = (Style)listView.FindResource("ListViewItemRow2");
        }
        else
        {
            st = (Style)listView.FindResource("ListViewItemRow1");
        }
        return st;
    }
}

Notice that the SelectStyle method first determines the index of the item being rendered. It uses this index to select a Style instance from the application’s static resources. I’ll get to these resources shortly.

Next I create an instance of this class in the application resource dictionary.

<controls:ListViewItemStyleSelector x:Key="ListViewItemStyleSelector"/>

The ListView property ItemContainerStyleSelector must be set to this or any other instance of my ListViewItemStyleSelector class. Actually ItemContainerStyleSelector is a property of ItemsControl, so this technique can be used on any ItemsControl, such as ListBox, not just the ListView used here.

<Style x:Key="{x:Type ListView}" TargetType="{x:Type ListView}">
  <Setter Property="ItemContainerStyleSelector" Value="{StaticResource ListViewItemStyleSelector}"/>
…
</Style>

Finally the two styles referenced by SelectStyle must be inserted into the application resource dictionary.

<Style x:Key="ListViewItemBase" TargetType="{x:Type ListViewItem}">
  <Setter Property="SnapsToDevicePixels" Value="true"/>
  <Setter Property="OverridesDefaultStyle" Value="true"/>
  <Setter Property="Foreground" Value="{StaticResource DarkForegroundBrush}"/>
  <Setter Property="Template" Value="{StaticResource ListViewItemTemplate}"/>
  <Setter Property="Margin" Value="2,0,2,1"/>
</Style>
  
<Style x:Key="ListViewItemRow1" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource ListViewItemBase}">
    <Setter Property="Background" Value="{StaticResource ListViewLine1Brush}"/>
</Style>

<Style x:Key="ListViewItemRow2" TargetType="{x:Type ListViewItem}" BasedOn="{StaticResource ListViewItemBase}">
  <Setter Property="Background" Value="{StaticResource ListViewLine2Brush}"/>
</Style>

Here I factored all of the common property settings into a base instance of Style named ListViewItemBase. The two Style instances used to render the ListView rows, ListViewItemRow1 and ListViewItemRow2, inherit these base settings using the BasedOn property: BasedOn=”{StaticResource ListViewItemBase}”.

This approach works great when the collection bound to ListView.ItemsSource is static, as it is in my test window. Everything breaks down, however, when items are added or deleted to the underlying collection.

I created a new Visual Studio project to isolate the ListView. In this project I bind ListView.ItemsSource to an ObservableCollection instead of specifying a collection of ListViewItems in my main window XAML as I did in the last example. Here’s the ListView in the new test window.

<ListView x:Name="_list" Margin="8" Height="120" Width="240" ItemsSource="{Binding}">
    <ListView.View>
        <GridView AllowsColumnReorder="true">
            <GridViewColumn DisplayMemberBinding="{Binding}" Header="Content" Width="100"/>
            <GridViewColumn DisplayMemberBinding="{Binding Path=Length}" Header="Length" Width="100"/>
        </GridView>
    </ListView.View>
</ListView>

And the relevant C# code in the code behind file.

private ObservableCollection<string> _items = new ObservableCollection<string>();
public Window1()
{
    _items.Add("First Item");
    _items.Add("Second Item");
    _items.Add("Third Item");
    _items.Add("Fourth Item");
    _items.Add("Fifth Item");
    _items.Add("Sixth Item");
    _items.Add("Seventh Item");
    _items.Add("Eighth Item");
    InitializeComponent();
    DataContext = _items;
}

I also added some buttons and text boxes to the test window to facilitate adding and deleting of collection items. Here are the relevant Button.Click event handlers.

private void DelButton_Click(object sender, RoutedEventArgs e)
{
    int n = 0;
    if (Int32.TryParse(_delItemNum.Text, out n))
    {
        if (n >= 1 && n <= _items.Count)
        {
            _items.RemoveAt(n-1);
        }
    }
}

private void AddButton_Click(object sender, RoutedEventArgs e)
{
    int n = 0;
    if (Int32.TryParse(_addItemNum.Text, out n) && String.IsNullOrEmpty(_addItemText.Text))
    {
        if (n >= 1 && n <= _items.Count)
        {
            _items.Insert(n - 1, _addItemText.Text);
        }
        else
        {
            _items.Add(_addItemText.Text);
        }
    }
}&#91;/sourcecode&#93;

The screenshot below shows what happens after deleting the third collection item.  Notice that the individual row background colors were not reset after deleting the item.  “Second Item” and “Fourth Item” are both the darker shade of gray.

<img src="https://patconroy.files.wordpress.com/2009/01/badlistview.jpg" alt="badlistview" title="badlistview" width="375" height="375" class="alignnone size-full wp-image-51" />

It turns out that once the item style is selected it will never be modified regardless of how the underlying data collection changes.  A workaround for this is to refresh the ListView’s collection view.  This can be done just after adding or deleting an item.

_items.RemoveAt(n-1);
System.ComponentModel.ICollectionView dataView =
    CollectionViewSource.GetDefaultView(_list.ItemsSource);
dataView.Refresh();

A better place to put this is in an event handler for ObservableCollection.CollectionChanged.

private void Items_CollectionChanged(object sender, NotifyCollectionChangedEventArgs e)
{
    System.ComponentModel.ICollectionView dataView =
        CollectionViewSource.GetDefaultView(_list.ItemsSource);
    dataView.Refresh();
}

Now the individual row backgrounds get reset correctly after items are added or removed from the data collection, and the alternating background color pattern is maintained.

The technique described here works for all ItemsControls in all versions of .NET that include WPF, 3.0, 3.1 and 3.1 SP1. A new feature was introduced in 3.5 SP1 that simplifies this a great deal. I’ll describe that in my next post. Stay tuned.


August 2017
M T W T F S S
« Apr    
 123456
78910111213
14151617181920
21222324252627
28293031  
I am a part of all that I have met;
Yet all exprience is an arch whitherthro'
Gleams that untravell'd world, whose margin fades
For ever and for ever when I move.
How dull it is to pause, to make an end,
To rust unburnish'd, not to shine in use!
Alfred, Lord Tennyson