CSLA .NET 3.8.0 alpha 1 available

CSLA .NET 3.8.0 alpha 1 available

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


RockfordLhotka posted on Saturday, August 15, 2009

I've put an early release of 3.8.0 online for download.

The primary areas of focus are in Csla.Silverlight and Csla.Wpf, and there are breaking changes to the XAML controls in those namespaces, so check the change logs for details. I've been focusing (so far) on InvokeMethod and PropertyStatus.

On the Silverlight side there's also a new ViewModel base class to help create viewmodel objects, and an enhancement to make CslaDataProvider.ObjectInstance bindable so you can probably use CslaDataProvider as a viewmodel object. I also added a new trigger action called Execute which offers a more modern (though more verbose) way to do something like InvokeMethod.

Also it occurs to me that CSLA .NET for Silverlight probably won't build if you don't have Expression Blend 3 installed. I'll have to figure out a solution for this - but in the meantime, if you don't have Blend 3 installed you'll need to comment out or remove the Csla.Silverlight.Execute class.

Finally, on the Silverlight side, MobileFormatter now defaults to using binary XML to serialize objects. This should reduce the memory footprint for n-level undo, and should reduce the size of the byte stream that goes over the data portal. There is a config option you can set to get the text XML serialization if you need that for some reason.

Unfortunately I haven't had time to do any testing with the binary XML in terms of perf or memory footprint, so I don't know if it makes a big difference or not. I got it implemented and working and that's about it...

I'm on vacation the week of August 17, so if there are any major issues just remember that this is a very early release and it will continue to change.

In fact - my primary motivation for putting this out right now is to get feedback and input, especially around the changes to InvokeMethod, PropertyStatus, the ViewModel base class and the Execute trigger action. If you have ideas on how these can be improved for the Silverlight 3 world I am eager to hear them!

paupdb replied on Monday, August 17, 2009

Hi Rocky

The two features I'm most interested in will be the ViewModel base and the binary xml serialisation - though I have already implemented both with Csla 3.7. 
Well on the binary xml side I am using binary encoding for the WCF end at least.

My current ViewModel base subclasses CslaDataProvider directly and then wraps several properties for easier/clearer binding syntax - for example the Data property.  So very keen to see what you have done.

Thanks for putting in the hard yards on this. 

Cheers

Paul

Jack replied on Monday, August 17, 2009

Paul,

Did you notice any measurable difference on the binary xml implementation?  Is it something you can share for 3.7?  I'm looking for some quickfix speed improvements but not sure if I want to put out Alpha software.

Thanks

jack

Jack replied on Monday, August 17, 2009

I did the upgrade solely to see the impact of the binary xml implementation.  My worst case object graph went from 33.5MB to 19.6MB and was seemed quicker to serialize/deserialize, and obviously was thus quicker to compress, send, and decompress.

I'm very pleased - now if I can just reduce the overall size I'll be golden.

jack

paupdb replied on Tuesday, August 18, 2009

Jack,

In my case, I had already implemented a custom WcfProxy class back in Csla 3.6 to include zip compression/decompression code using the SharpZipLib library.

So the subsequent move to using binary encoding for Wcf didn't reduce my object graphs by that much...although I plan to remove my explicit zip/unzip code to see how pure binary encoding goes.

That said I think Rocky has taken the binary xml even further into the framework itself for undo etc, so I'm expecting more reduction in terms of memory usage as well as transport objects with 3.8

RockfordLhotka replied on Sunday, August 23, 2009

Yes, my work in 3.8 was to make the actual object graph serialization use the binary format. That isn’t something you can control or affect through the WCF configuration.

 

If you care about the details, you should read my Silverlight blog posts about the MobileFormatter and how it was designed. At a high level it works like this:

 

1.       The business objects’ data is copied into a set of DTOs

2.       The DTOs are serialized using the DataContractSerializer

3.       The resulting byte array is stored in memory, or sent over WCF or whatever

4.       If it is sent over WCF, then obviously WCF serializes the message – including the byte array

 

So if you configure WCF to use binary encoding that affects step 4 in the process. I haven’t done thorough testing here, but I suspect you’ll see a 40-60% reduction of the data stream over the wire by doing this.

 

Of course you can also implement compression like I show in the video series, and that’ll radically reduce the size of the data stream over the wire – and the WCF config change will still shrink that by around half. So the WCF thing is a big deal.

 

My work in 3.8 is to affect step 2 in the process. The exact impact of this is difficult to know, and I didn’t have time to do any real testing. This change really affects the way the business object data is encoded, and so should have a pretty big impact, but probably more like 20-30% I would guess. Less than the use of compression or the WCF change.

 

I suspect that most people will want to have CSLA use the binary encoding for step 2 so that’s the default. I also suspect that most people will configure WCF to use the binary encoding. And that they’ll use compression. The three things combined should produce a really nice overall result.

 

Rocky

 

From: paupdb [mailto:cslanet@lhotka.net]
Sent: Tuesday, August 18, 2009 7:07 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available

 

Jack,

In my case, I had already implemented a custom WcfProxy class back in Csla 3.6 to include zip compression/decompression code using the SharpZipLib library.

So the subsequent move to using binary encoding for Wcf didn't reduce my object graphs by that much...although I plan to remove my explicit zip/unzip code to see how pure binary encoding goes.

That said I think Rocky has taken the binary xml even further into the framework itself for undo etc, so I'm expecting more reduction in terms of memory usage as well as transport objects with 3.8


Jack replied on Tuesday, August 25, 2009

Rocky,

Which sample application, if any of them, are you trying out these changes in?

Thanks

jack

RockfordLhotka replied on Tuesday, August 25, 2009

Right now I have two simple experimental projects (one for SL, one for WPF) that I’ve been using. They aren’t in svn, but perhaps I should add them to increase visibility.

 

 

From: Jack [mailto:cslanet@lhotka.net]
Sent: Tuesday, August 25, 2009 10:08 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available

 

Rocky,

Which sample application, if any of them, are you trying out these changes in?

Thanks

jack


Jack replied on Friday, September 11, 2009

Rocky,

 

When you put out Alpha 2 will you add your samples?

 

Thanks

 

jack

 

From: Rockford Lhotka [mailto:cslanet@lhotka.net]
Sent: August-25-09 9:19 AM
To: jaddington@alexandergracie.com
Subject: RE: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available

 

Right now I have two simple experimental projects (one for SL, one for WPF) that I’ve been using. They aren’t in svn, but perhaps I should add them to increase visibility.

 

 

From: Jack [mailto:cslanet@lhotka.net]
Sent: Tuesday, August 25, 2009 10:08 AM
To: rocky@lhotka.net
Subject: Re: [CSLA .NET] CSLA .NET 3.8.0 alpha 1 available

 

Rocky,

Which sample application, if any of them, are you trying out these changes in?

Thanks

jack



RockfordLhotka replied on Monday, August 31, 2009

One thing I'm looking at doing with ViewModel<T> is creating two classes.

ViewModelBase<T> - implements the Model property, public Can___() methods like CanSave(), and protected DoSave(), DoCancel(), etc. In other words, this class exposes no public verb/action/command methods.

ViewModel<T> - inherits from ViewModelBase and adds public verbs like Save(), Cancel(), etc. for use by InvokeMethod or the new Invoke trigger action.

The idea is that ViewModelBase can be used as a base class if you are using some other UI framework's commanding model. There are so many out there, and Microsoft has no standard for Silverlight and an iffy standard for WPF - so this would allow you to implement your verbs as required by your UI framework.

And ViewModel can be used as a base class if you are using the commanding model provided by CSLA .NET, which may be very useful if you are implementing your own UI framework.

Hopefully this is a way to make everyone reasonably happy :)

SonOfPirate replied on Tuesday, September 01, 2009

Rocky,

Any examples using the new ViewModel<T> class yet?  I was reviewing the code and it looks like you expect the Model property to be set externally - possibly through data-binding since it is defined as a DependancyProperty.  This has me a bit confused since it was my expectation that we would be doing something similar to the CslaDataProvider and supporting the asynchronous loading of the model object under-the-covers of the ViewModel.

In other words, I expected to see code in the Model getter that trigger an asynchronous method call to retrieve the instance and set it to the Model property.  Right now I don't see anything that resembles this.

Can you share your thoughts and intentions?  (Examples always work, too!)

 

RockfordLhotka replied on Tuesday, September 01, 2009

Creating the Model instance is something I haven’t figured out quite yet, and so I’ve moved on to working on some other things (PropertyStatus) while I think about it.

 

But this thread is a good place to solicit input.

 

The flaw in the data provider model is that there’s a really steep cliff.

 

If your object can be retrieved/created without parameters, or with hard-coded parameters, you can do everything in XAML.

 

But if your object requires variable parameters – especially if they need to come from a previous page/form – then there’s no real answer beyond code-behind.

 

One of my goals is to eliminate (or radically minimize) code-behind, so this means the data provider approach isn’t desirable, and this is one reason I haven’t replicated it in ViewModel<T>.

 

It seems to me that the ideal solution somehow involves the ViewModel being in control of the create/retrieve operation. And that somehow the ViewModel would have any parameters necessary to do the retrieve.

 

Since a very common scenario is that we got to the current form from a previous form, this implies that the previous form’s ViewModel has a way to pass parameters to this form’s ViewModel. In fact, it would be really nice if the previous form’s VM could actually create this form’s VM – or could invoke a Controller that does the creation. Something like that.

 

Then bring the various navigator models into the picture – either the SL 3 one or the CSLA one. They allow passing parameters as long as the values can be represented by text (in a URI), and the navigator component basically acts like a Controller.

 

So now you might argue that the primary model is that form A navigates to form B and provides the necessary parameters through the navigation URI. So now form B’s VM needs a way to get the parameters from that URI so it can initiate the retrieve of the Model.

 

There’s no scenario I can see where it is desirable for the XAML to trigger retrieval of the model.

tmg4340 replied on Tuesday, September 01, 2009

You know, for someone who didn't want to make a UI framework, you seem to be doing a lot of "UI framework"-type things lately... Smile [:)]

I've seen this come up a couple of different places, but I'm still confused about it.  What is the driving force behind the "no code-behind" concept?  Maybe I just haven't worked with WPF/Silverlight enough, but I'm still searching for a reason why code that isn't "visual candy" is such a Bad Thing.  I'm not talking about putting all your code in the code-behind - but I'm trying to figure out why a "Passive View" concept has become The Way.  Sure, it does make for easier testing - but since XAML (and the attendant technologies that use it) is still relatively immature, we seem to be going through an awful lot of hoops...

Ultimately, all you're doing is replacing developer's code-behind with yours.  I do realize there is a difference, and I know that a fair amount of the code would probably be boilerplate anyway.  But that could probably be handled through the UI framework you advocate developers build at the start of any project.  This code would arguably be simpler than what you're trying to do, since it can be built specifically to solve the application/navigation model they are building.  The more you do, the more complicated your code gets, because you have to try and cover the "80/20 Rule".

- Scott

RockfordLhotka replied on Tuesday, September 01, 2009

I won’t argue with you Scott – I’m not entirely sold on this MVVM thing myself.

 

I rather liked the data provider model, coupled with UI-oriented bits of code in the code-behind. I thought (and think) that it is a very effective and productive way to build the UI in XAML.

 

You’ll notice that I’m not dropping CslaDataProvider, and in fact 3.8 includes a couple really nice enhancements of the control to make it work better in master-detail scenarios. This is because I like the data provider model quite a lot, especially as I did it in Silverlight (WPF imposes some not-so-friendly constraints I’m not happy with).

 

At the same time the buzz is all around MVVM, and so I feel that it is very important that CSLA work with that model as well. I surely don’t intend on writing a UI framework, but there are aspects to some controls (like PropertyStatus) that make the MVVM approach less smooth than it could be.

 

Additionally, in my mind, if you create a ViewModel you are going to want a base set of behaviors when the Model is a CSLA business object, and so I’m creating a basic ViewModel base class (2 actually) to make it easier for MVVM people to create their VM types. If someone doesn’t like the base class, they can safely ignore it, but I suspect that most people will want their VM to include the stuff in my base classes.

 

In the end I absolutely think you are right: the ViewModel is just a different place to put code-behind. The only real difference I can see that matters is that it is more testable. Whether that is worth the increased complexity isn’t clear to me, but some people accept a lot of complexity and cost to get testability – and as a consultant I can’t complain if I’m on such a project because I get paid by the hour :)

paupdb replied on Tuesday, September 01, 2009

Rocky,

I fear any solution to these kinds of issues can only be generic to a certain point, since aspects involved in cases where parameters need to move around are subject to whatever navigation, MVVM and general application paradigms and design decisions made per project/company/application. 
For example in our application, navigation leverages the SL3 navigation controls but then feeds into a custom Shell which will dynamically download a module and instantiate the View - i.e. a composite application design along the lines of Prism 2 recommendations.

We found that the CslaDataProvider's Refresh/Save verbs plus the FactoryParameters array were quite usable in a ViewModel case, though we did extend it somewhat as you would have seen.
To manage the passing of parameters to the VM, we implemented a pattern/convention stating that all our VMs must have at least one Initialise method which accepts the parameters.  In some cases, our VMs have multiple Initialise methods to handle different possible parameter sets:

An example:
/// <summary>
    /// Initialise with a string of keywords
    /// </summary>
    public void Initialise(string keywords, DisciplineInfo discipline, ProjectInfo project)
    {
      this.ModelType = typeof(KeywordInfos).AssemblyQualifiedName;
      this.Criteria = new KeywordInfos.Criteria();
      this.FactoryParameters.Add(Criteria);
   
      Criteria.Keywords = keywords;
      Criteria.Project = project;
      Criteria.Discipline = discipline;
      Refresh();
    }

In the case above, the VM is for a dialog, so it is not directly accessible by a public url and thus we can pass objects into the Initialise.  Normal pages in our app - which are normally accessible by public url - have a restriction that all the parameters to the Initialise need to be primitives in order to be ToString'ed into a url query string portion.

To understand how we enforce the Initialise pattern, below is a snippet of code from our page loading class.  Basically our page loading class does the following:
1. Look up the View class matching the page number given in the url

2. Create the View dynamically using reflection

3. We mandate that all View's must have a StaticResource xaml line included for the ViewModel - this approach effectively creates the VM via parameterless constructor, but more importantly the VM is available in the XAML for data binding from anywhere in that View.
<vm:KeywordsSelectDialogViewModel x:Key="ViewModel" d:IsDataSource="true" />

4. Our page loading code then executes the code below to extract the VM from the View and executes the relevant Initialise based on the parameter object array given.
// Get the ViewModel out of the view's resources. 
      var vm = (view.Resources["ViewModel"] as ViewModelBase);

      if (vm == null)
        throw new ProjectionException("The ViewModel must be called 'ViewModel' and be declared in the top level Resources section of the View!");

      // Assign the View to the ViewModel
      vm.View = view;

      try {
        // Initialise the ViewModel
        vm.GetType().InvokeMember("Initialise", BindingFlags.InvokeMethod, null, vm, viewmodelParameters);
      }
      catch (Exception e) {
        throw new ProjectionException("Error calling ViewModel Initialise", e);
      }

      view.DataContext = vm;

Hope this helps explain one way that MVVM is implemented based on Csla and CslaDataProvider.

RockfordLhotka replied on Tuesday, September 01, 2009

Thanks Paul, that’s good input.

 

This is exactly why my current ViewModel base classes are very basic and don’t impose or implement any create/fetch behaviors. By leaving that out of the base classes, I allow you to very easily create your own VM base class (subclass of mine presumably) that adds whatever create/fetch model you need to integrate with your UI/navigation framework.

 

I’ve been doing something very similar to what you describe – requiring a convention by which the primary ViewModel for a form is a resource named “ViewModel”. That works for a lot of simpler forms, but is a little problematic for more complex forms where the form leverages multiple VM objects.

 

The thing is, as soon as I got to this point I realized that every UI framework out there will come up with a different set of such conventions. Since Microsoft hasn’t provided any standard around this, everyone will make up their own thing – and since I don’t want CSLA to become a UI framework, I don’t really want to make up one too – at least not in CSLA.

 

Rocky

paupdb replied on Tuesday, September 01, 2009

To answer the questions about why MVVM?

Every application/company is different and there is no definitive pattern that will solve all your problems, so really MVVM is certainly not the only way.
All I can provide is the list of reasons why I as an application architect decided to go with it:
1. Testability. 
Having what is effectively your code behind in a seperate class to the UI/View means that you can very easily test actions upon the UI - e.g. like when a button is clicked.  This is because your VM should have that action on it - usually associated to the View through an abstraction like a Command.  To write test classes against a VM is generally very easy.

2. Strong seperation of business, and UI logic.
This one really comes down to how well you enforce it, but provided you strictly put all business logic in the Model (a CSLA object), keep verbs/actions in the VM and only write View code-behind when you need to do something fancy on the UI (like a complex animation), you end up with a very nicely seperated code base.  Its also very easy to know where to look when you are investigating/debugging.

3. Extremely well suited to a pure data binding implementation (which in turn gives a pure XAML implementation).
Goes back to the testability, but also improves maintenance and general readability of code - at least in my opinion.

RockfordLhotka replied on Tuesday, September 01, 2009

The generic issue is a pain point right now. I was hoping to find a clever solution, but so far that hasn't worked, and I expect that my next move is to change the ViewModel classes to be non-generic.

I'm not sure we lose much by doing that, but it would have been nice if Model could have been strongly typed :(

I'll give serious consideration to implementing a create/fetch model in the ViewModel class (though probably not ViewModelBase) since it is somewhat more "CSLA specific" if that makes sense.

paupdb replied on Tuesday, September 01, 2009

Rocky,

Agree with you completely.  If you go too far in prescribing how to use MVVM with Csla, you risk imposing conventions/assumptions on everyone.

MVVM, MVC, MVP, etc - these are all valid approaches and Csla works very well with all provided one is willing to write some custom base classes to extend and implement paradigm-specific functionality.

In terms of providing a base VM class, I think having Refresh and Save verbs is fairly critical. 
From my perspective, the VM is "in charge", so it should control loading and saving the Model - thus I would say Refresh and Save are core to any VM.  Having an Error (or ModelError) property is probably also fairly core.

If you provide these using an implemention ala the CslaDataProvider, but ensure that the methods are virtual, then users can simply override and customise how they want the Refresh/Save to work.

Ultimately I keep coming back to the CslaDataProvider because its really got a lot of the methods and properties that what I want in most of my VMs.  Its only some DataProvider specific things in the CslaDataProvider which makes it harder to work with from a VM perspective.

I'm beginning to think I may not use any ViewModel classes you put out in Csla anyway.  There are too many specific things I want to do.
I may just take a copy of the CslaDataProvider, rip out all the DataProvider stuff (bye bye ObjectInstance/Data) and make that my ViewModelBase.

Maybe instead of doing a ViewModel base class, you should consider doing that in Csla too - i.e. create a base CslaProvider class which is everything CslaDataProvider is but with none of the DataProvider specific bits plus everything is marked as virtual for easy subclassing.

RockfordLhotka replied on Tuesday, September 01, 2009

What I'm not sure is where the value comes in in ViewModel implementing a Refresh() method.

To do MVVM you need a commanding infrastructure of some sort - beyond the WPF one, and of course there isn't one in SL.

Everyone's commanding infrastructure is different, and imposes different constraints on the verb method signatures.

This means there's no value in ViewModelBase providing any public methods at all, because we must assume they'll have the wrong signature for most UI frameworks.

I am implementing ViewModel as a subclass of ViewModelBase, and ViewModel implements a set of base verbs that work with CSLA's Invoke action and InvokeMethod property (two ways to do the same thing). Essentially ViewModel supports CSLA's commanding implementation.

But a general Refresh() method would then have to be protected, because everything in ViewModelBase is protected (all methods anyway).

And since I don't know how to get your criteria/parameters, or which factory method (if you are using factory methods) to invoke on your type to do a refresh, I can't provide any implementation at all really.

Even if I add a protected property so you can set the name of the factory method in your VMs ctor, I still don't know where to get any parameters.

And there's also the concept of a child VM - a VM that exists inside a DataTemplate, or even on the main form, but to manage some set of child or detail data. There is no concept of "refresh" on something like that, because it gets its data through binding to the parent VM.

I could go down the data provider route: have you tell me the name of the static factory and have a protected List<object> for parameters. But I am not sure this saves any code or effort on the part of someone implementing the VM.

paupdb replied on Tuesday, September 01, 2009

Yes I see what you mean Rocky - I guess I'm probably talking from a fairly specific implementation perspective.

In terms of the value of having Refresh/Save and FactoryParameters/Criteria - even if these were implemented as protected, I think there is still value gained by having a default way of managing the async calls and the errors/results of these. 
However the approach you have of making the ViewModel base a generic for the Model type is intriguing too - though I don't think one can use a generic class type as a StaticResource in XAML, so I'm probably left using the CslaDataProvider approach of assigning the ModelType in my VM Initialise/ctors.

I think the whole discussion has highlighted to me that I need to take my own base VM class away from inheriting from any Csla class.
That said I think the core bits of CslaDataProvider are very applicable to my implementation and thus will probably find their way into my own VM base.

Even if MS put out a MVVM framework/standard tomorrow, my application is far enough along with our custom implementation that we won't change now.  We might incorporate some good elements from such a standard, but I doubt we'd rewrite what is already a decent custom MVVM implementation.
Given my specific implementation I can't expect Csla to give me a ready made VM base nor can I expect Rocky to modify the CslaDataProvider to make it everything I want for a base VM class.

So really then maybe the value of having such classes in Csla at all is more to provide a reference implementation for people to learn/borrow from when rolling their own MVVM.  In other words something along the lines of what Patterns and Practices do where they release code as reference backing to their recommendations.

SonOfPirate replied on Tuesday, September 01, 2009

This is why I was wondering if you had any examples using the new ViewModel class because I think that may lead to an answer.

Going along what I was thinking, I could see the ViewModel providing the "hooks" for create/fetch while leaving the implementation to the subclass.  So, for instance, in the Model property getter, if the model is null, call the Refresh or GetData abstract method.  Since the Model property setter is accessible, the subclass can use whatever means to retrieve or create the object then set the base class property which will raise the necessary event(s) for data-binding to update the UI.

If I'm doing an asynchronous fetch, Refresh/GetData will start the process and some handler in the subclass will be called when completed and the latter will set the Model property.  Seems like the best of both worlds.

The whole process is triggered in the same manner as with the CslaDataProvider.  When data-binding polls the Model property, if null...  You could even include an option for InitialLoadEnabled.

I like the fact that CslaViewModel is abstract and intended for us to subclass.  I found myself subclassing the ASP.NET CslaDataSource more often than not as a way to encapsulate the logic and make it easier for designers to work with the features consistently.

 

To the previous question about no code-behind, I just had the exact same conversation this morning.  From my perspective, it really boils down to the idea that these applications are developed by two distinct roles: developers and designers.  The latter are graphics/UI people who know how to make great looking interfaces but may not know - or more accurately, are not required to know - how to code.  Developers on the other hand, tend to make lousy user interfaces.  We put square controls in a table-like grid layout and call it done.  If you think about the roles Visual Studio and Expression Blend play in the development process, you'll see that it is consistent with this thinking.

So, I think the goal is to decouple the code that developers work on from the XAML that designers work on.  That's where this stems from.  And, imo, I think it is a good thing because it does encapsulate code a little better and allows me to follow this approach to developing my applications.  I no longer have developers waiting for designers to check in changes to the UI so they can make code changes and vice versa.

 

Finally, speaking from very recent experience, locking in how things are done so strictly as to define the name that must be used, etc. only makes code more unusable instead of the other way around.  We tend to present these architypes as patterns, approaches and solutions that should be applied when and where they fit.  They should be flexible to fit the situation, not dictate every aspect.

I worked with a brilliant developer not to long ago that had created a UI framework for the company's applications that made it a snap to generate a robust Windows Forms application quickly by subclassing types in his framework.  The problem?  He wasn't a student of data-binding so when a new developer (me!) tried to work with his framework using some of the latest tools and techniques, including Csla, his framework fell apart because it was way too rigid in its implementation.

Just my two cents.

 

tmg4340 replied on Tuesday, September 01, 2009

SonOfPirate:

To the previous question about no code-behind, I just had the exact same conversation this morning.  From my perspective, it really boils down to the idea that these applications are developed by two distinct roles: developers and designers.  The latter are graphics/UI people who know how to make great looking interfaces but may not know - or more accurately, are not required to know - how to code.  Developers on the other hand, tend to make lousy user interfaces.  We put square controls in a table-like grid layout and call it done.  If you think about the roles Visual Studio and Expression Blend play in the development process, you'll see that it is consistent with this thinking.

So, I think the goal is to decouple the code that developers work on from the XAML that designers work on.  That's where this stems from.  And, imo, I think it is a good thing because it does encapsulate code a little better and allows me to follow this approach to developing my applications.  I no longer have developers waiting for designers to check in changes to the UI so they can make code changes and vice versa.

I must be working in the wrong places, because in the years I have been programming (admittedly only about 13), I have never worked in an environment where the UI designer and coder were different people.  I understand that's the model that MS is trying to go for with the whole Blend/VS thing, and that's OK.  I just don't see that taking off too well in the MS world - Microsoft has not traditionally recruited the "artsy-fartsy" crowd very well.  Smile [:)]  Also, it didn't take long for developers to b**** about the crappy XAML designer support in VS 2008 - something I understand MS intends to rectify with VS 2010.  Realizing that MS has to support both types of development, I'm honestly not going to get much traction asking my boss to hire a "UI Experience designer" when they know that the next version of VS will fix many of my issues - presumably in a format that is not so art-designer-centric (and thus not such a steep learning curve for those of us who are "artistically challenged").

As far as the encapsulation aspect, that's certainly a good goal to have, and you certainly do raise a point about "waiting for designers".  But I find the whole thing to be a lot of quibbling over what feels like semantics to me.  And in the end, the whole no-code-behind MVVM seems to make your coders do more work than they might have to/should.  After all, once you take the "event code" and move it one layer away from the actual event, you end up writing a certain amount of code just to transfer control around.  This code is very boilerplate, and typically can't be abstracted out.  Sure, you can test it.  But it all ends up being more code, which means more test code...

Apparently too old-school for his own good...

- Scott

Jaans replied on Friday, September 04, 2009

Hi Rocky

Hope you had a good vacation - usually it's just enough to make you need more ;-)

I'm had an early look at 3.8.0 (Alpha 1) and I have a found an issue with using InvokeMethod to target a CslaDataProvider.

For the life of me I cannot see what's wrong - the code originally worked fine using 3.7.0 and now with 3.8.0 (and after changing "Resource" property to "Target") it just doesn't work as expected anymore.

Perhaps I'm using the wrong syntax to reference the CslaDataProvider in the Target property. Here is a snippet of the relevant XAML:

&lt; Button Content="Save" Margin="2" csla:InvokeMethod.TriggerEvent="Click" csla:InvokeMethod.Target="{StaticResource WorkOrderData}" csla:InvokeMethod.MethodName="Save" />

My issue is that the button never enables, eventhough CanSave on the data provider is true. I've tried the whole "ManualEnableControl" bit just to see if it has any effect if, but alas it doesn't.

It is as if the InvokeMethod doesn't find the method Save on the Target.

Any help would be appreciated.

Regards,
Jaans

RockfordLhotka replied on Friday, September 04, 2009

I'm afraid the snippet didn't come through, can you retry?

Certainly the syntax of Target is different, and it will change again in
Alpha 2 - I'm working to make these all binding-based.

I can't honestly remember what syntax was right in A1 vs what I have right
now, but now it is a full binding expression, if you set it at all. The idea
is that you wouldn't normally set it, because the Target is also the
DataContext, which is the CslaDataProvider.

Jaans replied on Friday, September 04, 2009

Oops... missed that (I updated the original post).

Having the InvokeMethod default to the DataContext is great and probably more consistent behaviour. In this scenario, my current DataContext is actually on the Data property of the CslaDataProvider so that's why I need the button in question to reference the CslaDataProvider itself.

I have tried specifying a Binding expression for Target that binds to the CslaDataProvider but it doesn't work (yet).

Any thoughts about when Alpha 2 might hit the release button :-)

Many thanks

RockfordLhotka replied on Friday, September 04, 2009

I'll probably do an A2 release next week sometime. The changes to
InvokeMethod (and the new Execute trigger action) and PropertyStatus are
pretty substantial - which is bad from a backward compat perspective, but
are a big deal for exploiting the SL3 features.

I should point out that all the real work here is in SL, not WPF. Once I'm
comfortable with the SL behaviors I'll port things to WPF.

Copyright (c) Marimer LLC