Stuart Davies
Stuart Davies

Reputation: 171

Data binding a WPF ListBox in response to a WCF service invocation

Picture, if you will, a Visual Studio 2008 WPF application with a single window containing a ListBox. This application contains a method, outlined below, that binds the ListBox to the contents of a database table.

This application also happens to implement a WFC service contract, hosting said WCF service.

The data binding method below is invoked in respose to both a button press on the window, and in response to a method being remotely invoked against the WCF service hosted by the application.

When invoked by the button press the binding works correctly and the list box reflects the content of the database table. I can insert some records into the underlying table, hit the button and the contents of the list box are refreshed to reflect the new records. However, when triggered remotely via the WCF service any changes to the database are not reflected in the list box. From stepping through the code the data set contains the correct view of the table, but the list box retains the previous view of the table and doesn't reflect the contents of the data set.

Initially I thought this sounded like a threading issue, so I tried making use of Dispatcher objects but to no avail. From my investigations both calls are received on the UI thread anyway.

Any suggestions appreciated - it's probably something blindingly obvious knowing my luck...

    private void BindData()
    {
        SqlConnection connection;

        using (connection = new SqlConnection(CONNECTION_STRING))
        {
            DataSet dtSet = new DataSet();
            SqlCommand command = new SqlCommand("SELECT * FROM TheTableWithMyStuffIn", connection);
            SqlDataAdapter adapter = new SqlDataAdapter();
            connection.Open();
            adapter.SelectCommand = command;
            adapter.Fill(dtSet, "TheTableWithMyStuffIn");
            listBox1.DataContext = dtSet;
        }
    }

UPDATE: I re-implemented the remote notification mechanism to use remoting rather than WCF, and the databinding now works when invoked both remotely and locally. There must be some contextual implication of using WCF?

Upvotes: 2

Views: 2182

Answers (3)

Kieron
Kieron

Reputation: 27107

Have you tried checking out the Service Trace Viewer that comes with .Net 3/ .Net 3.5/ Windows SDK?

May be worth checking out the messages that are bouncing around, see if the anything presents itself there.

Good luck.

EDIT:

You may want to try this article on detecting silent data binding errors...

Upvotes: 2

Damian Powell
Damian Powell

Reputation: 8775

I'm not sure if DataSet implements the appropriate interfaces to automagically cause a WPF list box to update, but assuming it does, try this: rather than creating a brand new DataSet and assigning it to the list box, try re-filling the same instance from the database. If I was writing this, I'd probably use an ObservableCollection<T> field rather than a DataSet but that implies that you'd need to move your data into a DTO or an entity.

Upvotes: 1

NickFitz
NickFitz

Reputation: 35031

I'm probably totally off-beam here given that I haven't had anything to do with .NET for years, but nobody else has offered an answer so far, so here goes.

From a quick scan of the MSDN documentation on how data binding is implemented in the .NET framework, I get the impression that updates to controls are dependent upon events that are fired when properties of the bound data source change. I notice that, in the code you present, the DataContext property of the ListBox has the new DataSet assigned to it after the data has been retrieved via the Fill method.

Could it be that, with the data having already been retrieved, some event which should cause the ListBox to realise the updated data is there is happening too soon? One would assume that the setting of the DataContext property would be sufficient to cause it to update; but given that there seems to be an awful lot of plumbing behind the scenes of the framework, and that the ListBox successfully updates when modified in a different context, I would begin to suspect a leaky abstraction: that is, that although something works as expected when used in one way, it fails when used in another way, because the underlying plumbing is (although not necessarily faulty) different.

Maybe assigning the DataContext property before filling the DataSet would make the difference. Or maybe this is just a superficially reasonable guess, but totally and obviously wrong and serves only to betray my almost complete lack of knowledge of .NET's internals.

Either way, good luck :-)

Upvotes: 1

Related Questions