Is it possible to bind the DataContext to CslaDataProvider's ObjectInstance VIA xaml?

Is it possible to bind the DataContext to CslaDataProvider's ObjectInstance VIA xaml?

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


mamboer posted on Thursday, March 19, 2009

I put a CslaDataProvider to a usercontrol,and try to do sth like:
    <UserControl.Resources>
        <csla:CslaDataProvider x:Key="vmReturnBatch"
             ManageObjectLifetime="True"
             IsInitialLoadEnabled="False"
             ObjectType="XXX.Core.CslaBO.PackingSlipReturnBatch,XXX.Core"
             ObjectInstance="{Binding}"/>
    </UserControl.Resources>

    but it fails...

    Since the static resources is part of the UserControl,is it possible to do binding in the static resources?
    I'm a lazy cat that i even don't want to write anything in the code-behind just like:
             var cslaDataProvider = this.Resources["vmReturnBatch"] as Csla.Silverlight.CslaDataProvider;
            cslaDataProvider.ObjectInstance = this.DataContext;

RockfordLhotka replied on Thursday, March 19, 2009

I'm guessing it won't work right now, but if it did, the syntax would be:

ObjectIntsance="{StaticResource MyOtherProvider}"

The problem is, MyOtherProvider would be a data provider, and what you really want is for it to bind to the Data property of that provider.

Though I'm not entirely sure that this is what you are after?

mamboer replied on Thursday, March 19, 2009

Hi,my scence happens in a common kind of Master/Detail view design,

1,In the master view,it shows a list of business objects.
  When you double click a record,the master view will popup a detail view for modification,and pass the selected BO to the detail view.(I just don't wanna do inline edit in the master view here.)

  Something like:
  var detailView=new XXDetailView();
  detailView.DataContext=SelectedBO;

2,I then wanna use a CslaDataProvider in the detail view,it's objectinstance will be set to the detail view's DataContext..I need that CDP to manage the selected BO's state,such as CanSave,etc.

  That's it.

RockfordLhotka replied on Thursday, March 19, 2009

I am somewhat skeptical that this can be done with a data provider, because a data provider has to be in a resource block, and is therefore global to the form.

 

What you want, and I agree that this is valuable, is a control that can exist in the visual tree within the scope of a region of the form – such as within a StackPanel bound to a child collection, or even to a line item within a DataTemplate.

 

But you can’t put a data provider into those locations, because it is not a UIElement, so it wouldn’t be legal XAML.

 

I’ve thought about this, and just haven’t had time to act on it, but I think the answer is to have an “object manager” control that is a UIElement, but which has no visual representation, so it could sit in the visual tree, and it could also act as a data source using relative binding. This would work in WPF anyway – but not Silverlight 2.0.

 

Rocky

mamboer replied on Thursday, March 19, 2009

Thank you very much!
And i like your Object manager idea,that's what i exactly need.
Suppose that we have a object manager with a name "omXXX",when passing a business object to my detail view,i just write sth like:

var detailView=new DetailViewXX();
detailView.onXXX.ObjectInstane=SelectedBO;

That would be fantastic!

RockfordLhotka replied on Friday, March 20, 2009

I'd hope that the ObjectManager concept would mean you could write no code. Ideally you'd be able to use binding - something like this pseudocode:

<DataTemplate>
  <StackPanel>
    <csla:ObjectManager Name="manager" />
    <TextBox Text="{{Relative binding expression to manager}, Path=Name}" />
  </StackPanel>
</DataTemplate>

Or for a child collection in a subpanel of a form:

  <StackPanel DataContext="{Path ChildList}">
    <csla:ObjectManager Name="manager" />
    <TextBox Text="{{Relative binding expression to manager}, Path=Name}" />
  </StackPanel>

mamboer replied on Friday, March 20, 2009

Maybe i meet what you mean.
You have to load the BO from server through that ObjectManager(More like CslaDataProvider,but a UserControl),don't you?
But in my master/detail design,why just pass the selected BO to the ObjectManger without making a client/server round trip?

RockfordLhotka replied on Friday, March 20, 2009

In my mind I don’t see ObjectManager replacing CslaDataProvider. So ObjectManager wouldn’t have a Save() method for example, because that’s something a CslaDataProvider should manage.

 

ObjectManager would have methods and behaviors to deal with child objects and child lists. So AddNew(), Cancel(), Remove() and so forth.

 

Rocky

RockfordLhotka replied on Wednesday, March 25, 2009

I have a possible solution for this issue - one that leverages the existing CslaDataProvider functionality.

The challenge we face is getting the binding value into the CslaDataProvider. While you can define a CslaDataProvider as a resource inside a DataTemplate, I can find no way to get data binding to set any of its properties - it just doesn't appear that resources work that way inside a DataTemplate.

The solution I've come up with for the InventoryDemo app is to create a BindingConnector object that sets the ObjectInstance property of the CslaDataProvider.

So the DataTemplate looks like this:

          <DataTemplate x:Key="EditProduct">
            <Grid>
              <Grid.Resources>
                <csla:CslaDataProvider x:Key="Product"
                                       ObjectType="InvLib.ProductEdit,InvLib"
                                       ManageObjectLifetime="True"
                                       IsInitialLoadEnabled="False"
                                       Saved="Product_Saved"/>
              </Grid.Resources>
              <this:BindingConnector ObjectInstance="{Binding}"
                                     DataProvider="{StaticResource Product}"/>
              <StackPanel>
                <StackPanel Orientation="Horizontal" Margin="0 0 0 5">
                  <TextBlock Text="Id" Width="100" />
                  <TextBlock Text="{Binding Path=Id,Mode=OneWay}" />
                </StackPanel>

The BindingConnector bridges the gap between the data provider and the business object provided to the DataTemplate by data binding. All the BindingConnector does, is sets the data provider's ObjectInstance property to its ObjectInstance property, which is {Binding}.

This means that the DataTemplate can contain Button controls that use MethodInvoker to interact with the data provider to do things like Cancel or Save. Look at the ProductList form to see how this works.

mamboer replied on Wednesday, March 25, 2009

Thanks so much! I will check it out later on.
And i will think on it whether we can make a better choice.:)

mamboer replied on Wednesday, March 25, 2009

If our SL control has a DataContextChanged event,we can hook the event in the CslaDataProvider. But no fortune,MS doesn't provide that event for SL...

RockfordLhotka replied on Wednesday, March 25, 2009

Yes, that event is very important. It is the reason some of the CSLA controls use a “Source” property, which is really not needed, except that it is the only way we can detect that the data source (DataContext) has changed. Very sad.

 

Rocky

 

 

From: mamboer [mailto:cslanet@lhotka.net]
Sent: Wednesday, March 25, 2009 12:51 PM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] RE: RE: Is it possible to bind the DataContext to CslaDataProvider's ObjectInstance VIA xaml?

 

If our SL control has a DataContextChanged event,we can hook the event in the CslaDataProvider. But no fortune,MS doesn't provide that event for SL...


Copyright (c) Marimer LLC