CslaDataProvider chaining?

CslaDataProvider chaining?

Old forum URL: forums.lhotka.net/forums/t/7998.aspx


jjhartma posted on Sunday, November 15, 2009


I'm writing a simple WPF address book app.  I have a details form that shows the Person record with 2 listboxes, one for Addresses and one for Contact Numbers.

When the user double clicks on an Address in the listbox a dialog comes up to edit that address.

Currently, I have a CSLADataProvider that manages my Root object and I bind all the controls to that, including the Listboxes.  I have DataTemplates that handle displaying the child objects.

The problem I'm seeing is that if I make a change to one of the addresses, that change doesn't update the listbox.  It does update the root object IsDirty and IsSavable flags, but I can't see the change on the details form.

Is there a correct way to bind these objects?  Do I need another CslaDataProvider for each child list, and if so, how do I chain them together?

I would also like the dialog that comes up to allow them to "Save" and "Cancel" changes to the address, without saving the actual object until the Root object is saved.  Is there anything special I have to do here?

Thanks for looking at my problem.

RockfordLhotka replied on Monday, November 16, 2009

I'll try to focus on the CSLA-related aspects to this question. Some of what you are asking is just WPF development skills and techniques.

You can use a CslaDataProvider on both the main form and dialog. In the main form you'll probably have it actually get the data by calling a factory method.

    <csla:CslaDataProvider x:Key="data"
                           FactoryMethod="GetList"
                           ObjectType="{x:Type this:DataItemList}"
                           ManageObjectLifetime="True"/>

In the dialog form you will not allow it to call a factory method, and instead will somehow (probably in code-behind) set the ObjectInstance property.

    <csla:CslaDataProvider x:Key="data"
                           ObjectType="{x:Type this:DataItem}"
                           ManageObjectLifetime="True"
                           IsInitialLoadEnabled="False"/>

How you do your code-behind can vary a lot, depending on how you decide to structure your application and its code. But the basic concept is pretty straightforward - this code is in the main form and sets up and displays the dialog:

    private void ListBox_MouseDoubleClick(object sender, MouseButtonEventArgs e)
    {
      var selected = DataList.SelectedItem as DataItem;
      if (selected != null)
      {
        var dlg = new Window2();
        var dp = dlg.Resources["data"] as Csla.Wpf.CslaDataProvider;
        dp.ObjectInstance = selected;
        dlg.ShowDialog();
      }
    }

The key is that I'm setting the ObjectInstance property of the data provider in the dialog. The last bit is the Save button event handler in the dialog:

    private void SaveButton_Click(object sender, RoutedEventArgs e)
    {
      var dp = Resources["data"] as Csla.Wpf.CslaDataProvider;
      var obj = (DataItem)dp.Data;
      obj.ApplyEdit();
      this.Close();
    }

Because I told the data provider in the dialog to manage the object's lifetime, I need OK/Cancel buttons that call ApplyEdit() and CancelEdit() before closing the form.

Copyright (c) Marimer LLC