BusinessListBase vs BusinessBindingListBase

BusinessListBase vs BusinessBindingListBase

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


tiago posted on Sunday, May 30, 2010

Hi all.

Sharing some experiences and raisising a point.

As you might have noticed, under CSLA.NET 4 BusinessListBase changed - when the collection changes, instead of raising the ListChanged event as it used to, it raises the CollectionChanged event.

This is old news and is all on the release notes. If you want to migrate your Windows Forms projects to CSLA.NET 4 all you have to do is to use BusinessBindingListBase.

I have this Windows Forms project and after porting (almost) everything from CSLA.NET 3.0.5 to CSLA.NEt 4.0.0 I got very weird problems using a DataGridView, like the list pointing to the wrong item, deleted rows didn't go away, etc. That was weird because there were a lot of errors and not that easy to reproduce.

I went to my library classes and just replaced BusinessListBase with BusinessBindingListBase and Bingo! All of a sudden the project was all right!.

Besides sharing the experience, I think this also raises a point. If we must use BusinessBindingListBase for Windows Forms and BusinessListBase for WPF/Silverlight, suppose my application has both clients. I need to have duplicated Business*ListBase classes?

Not to mention the WPF/Silverlight issue. I can see that the sample projects (PTracker) use conditional compiler directives to keep different implementations on the same source.

Of course we can use the same trick for the WindowsForms / WPF issue:

#if WPF
    public partial class Folders : BusinessListBase<Folders, Folder>
#else
    public partial class Folders : BusinessBindingListBase<Folders, Folder>
#endif

We can have conditional compiler directives for 3 UI environments and I'm afraid that soon enough programs risk to get unreadable. One has to find its way through the conditional compiler directives instead of browsing code. I mean we will be debuging conditional compiler directives instead of debuging code.

RockfordLhotka replied on Sunday, May 30, 2010

tiago

Besides sharing the experience, I think this also raises a point. If we must use BusinessBindingListBase for Windows Forms and BusinessListBase for WPF/Silverlight, suppose my application has both clients. I need to have duplicated Business*ListBase classes?

Not to mention the WPF/Silverlight issue. I can see that the sample projects (PTracker) use conditional compiler directives to keep different implementations on the same source.

Several months ago, perhaps even a year ago, I started a thread to discuss what CSLA 4 should do about the Windows Forms vs WPF/SL app problem. There is no good answer. None.

My first instinct was to drop Windows Forms entirely. That was rejected (with good reasons) by many people on the forum. The approach taken by CSLA 4 is (imo) the only meaningful alternative - provide a set of collection types for Windows Forms, and update the primary collection types to work with everything else.

I have absolutely no idea how to make one list work for both Windows Forms and XAML. I do not believe it is possible, not in any realistic sense.

When it comes to ProjectTracker - that is VERY far from being complete for CSLA 4. I have just started the process of making it work for Silverlight, which is where the compiler directives come in. That's pretty typical for any SL app - your objects will have some minor differences between SL and .NET that must be addressed. We've worked very hard to minimize those differences, but some things just can't be hidden (you can't have data access or synchronous factory code in your SL code - that just isn't possible).

ProjectTracker does work for ASP.NET MVC, as that's been my focus with that particular project so far. That's not done either, but the functionality that is there does work. Next I'll be working on the Silverlight client, then WPF. The Windows Forms client will probably go away in ProjectTracker - or will move to a completely separate version of the sample - specifically because the collection types can't be shared between Windows Forms and the rest of the UI technologies...

frankhoffy replied on Thursday, February 17, 2011

I must say, this makes me pretty nervous about upgrading.  We're in CSLA 3.8.3 and have libraries that are used across WPF, Windows Forms, and the Web.  BusinessListBase is used everywhere.

RockfordLhotka replied on Thursday, February 17, 2011

If your objects are working now, then just switch your base classes to the "BindingListBase" versions and you'll get the same behavior as 3.8. Literally, because those are the original types from 3.8, just renamed :)

Nothing forces you to use the "ListBase" versions. I just view them as the default from CSLA 4 and higer, because I suspect people will migrate away from Windows Forms and onto the modern UI technologies as time goes on.

tiago replied on Thursday, February 17, 2011

RockfordLhotka
(...) I suspect people will migrate away from Windows Forms and onto the modern UI technologies as time goes on.

You're right. WPF is so much easier than windows forms...

frankhoffy replied on Thursday, February 17, 2011

Thanks for the reply Rocky.  I see it now in the release notes.  I'm going to push for a CSLA 4.x upgrade for us this year.

Miroslav Galajda replied on Thursday, May 19, 2011

I'm starting with CSLA 4.1 and I am very sad that I must first make a decision for what UI will be the business object used.

Rocky, you didn't asnwer what to do in a such situations when one wants to use business object both in Windows Forms and WPF.

This is insane that when designing business object I need to take in the consideration in what UI it will be used.

What do you propose?

ajj3085 replied on Thursday, May 19, 2011

If you need to support WinForms, you're stuck with BindingListBase subclasses.  Things should mostly work in Wpf.  Keep in mind, this isn't Rocky's doing; MS invented ObservableCollection for Wpf, and then didn't make Wpf fully honor BindingList, nor WinForms work at all with OC.

Personally, I wouldn't support two different rich client UI technologies; make your app in one or the other and code your BOs accordingly.

RockfordLhotka replied on Thursday, May 19, 2011

Miroslav Galajda

I'm starting with CSLA 4.1 and I am very sad that I must first make a decision for what UI will be the business object used.

I am sad too. As I've said numerous times, Microsoft really created a no-win situation for anyone trying to migrate from Windows Forms to WPF, and that's very unfortunate.

Andy is correct, the ideal solution is to not support both at once. Of course that's not realistic if you have an existing CSLA .NET Windows Forms app and need to migrate to WPF over time. In that case you are really left with migrating groups of related functionality as a unit, so you can convert the business objects from BBLB to BLB as you recreate the UI in WPF.

On the other hand, the problem is (almost) entirely restricted to Windows Forms. The CSLA 4 BLB and ROLB types work fine in all other technologies other than Windows Forms. Given the efffective legacy status of Windows Forms, the issue really only impacts people who do need to migrate existing CSLA .NET Windows Forms apps forward.

The one exception I'm aware of, is that some third party WPF datagrid controls apparently don't work correctly with ObservableCollection types, and therefore also require the use of BBLB and ROBLB. My recommendation is to either contact that vendor to see if they do also support ObservableCollection, or choose another third party component vendor that does support ObservableCollection in WPF.

Are any of these solutions ideal? No. Is there an easy answer? No (barring Microsoft fixing the mess they made - and that's unlikely at this point).

Miroslav Galajda replied on Friday, May 20, 2011

Thank you for your explanation.

In 3.8.4 there was one type of collection to support all UI technologies. And it worked, right? What has changed that you made two separate collections in 4.x versions? It was change in .NET 4.0 version or what?

I need to make serious decision and I'm looking what will not work if I use the latest 3.8.x version instead of 4.x for both WinForms and WPF and the others.

That was the strongest point of CSLA that one can create only one business layer on top of CSLA and this business layer can be used in all of UI worlds.

Thank you.

JonnyBee replied on Friday, May 20, 2011

The 3.8.4 BusinessListBase and 4.x BusinessBindingListBase is essentially the same classes (just renamed in 4.x).

The problem here is (as described by previous posters) that WPF collection databinding does not fully support IBindingList. WPF prefers IObservableCollection and it is not possible to create one  list class that implements both interfaces.

This has nothing to with .NET4 - the same problem goes for .NET 3.5.

CSLA tried to keep the IBindingList based classes but too many issues with databinding, grids, sorting and more forced the move to 2 separate list classes.

So - the "new" 4.x BusinessListBase /ReadOnlyListBase is the recommended approach for all UI technologies except for WindowsForms that requires BusinessBindingListBase / ReadOnlyBindingListBase.

But yes, if you need the same BO assembly to be used for both WindowsForms and WPF then using the old classes will work but you will run into issues in the WPF client that simply does not work as expected and must make workaround and manually code your fix.

Miroslav Galajda replied on Friday, May 20, 2011

Are those issues somewhere documented?
You should understand my concerns.
This should be standard approach. If someone has made an effort to overcome those issues it would be very useful to list them and make other one to consider them.

This is crucial for everyone who is migrating form 3.8.x version to 4.x version and even more for those who still maintain development on windows forms but are planning to support at the same time one of the other UI platforms.

JonnyBee replied on Friday, May 20, 2011

I am not ware of anyone that has documented all those issues. If anyone has then please let us know!

Remember - these issues are not likely to be CSLA specific.

They are mainly caused by WPF introducing new collection classes and partial support for IBindingList list classes used in Windows Forms.

And another bulk of issues comes from third party grid controls in how good they support both interfaces.

I know sorting and filtering has been asked multiple times when using IBindingList classes in WPF with the MS DataGridView.

RockfordLhotka replied on Friday, May 20, 2011

Miroslav Galajda

In 3.8.4 there was one type of collection to support all UI technologies. And it worked, right? What has changed that you made two separate collections in 4.x versions? It was change in .NET 4.0 version or what?

That statement is not correct.

In 3.x there was one type of collection, and it worked well with everything except WPF. CSLA 3.x collections only partially worked with WPF, because WPF only partially supports IBindingList (BindingList<T>).

I spent years not fully supporting WPF, because it wasn't used widely enough (in my observation) to make it worth the pain.

Starting with Visual Studio 2010 there's a working deisgner for WPF, and Magenic started to see a major increase in the use of WPF. I thought it was time to accept the pain, and provide a collection type that supports WPF.

Because a collection that works with WPF also works with everything except Windows Forms, and because I view WinForms as legacy technology, I made the "default" BusinessListBase and ReadOnlyListBase support WPF. I just renamed the old classes to BusinessBindingListBase and ReadOnlyBindingListBase and kept them for support of Windows Forms apps.

Miroslav Galajda replied on Friday, May 20, 2011

Two questions:

1) What UIs are fully compatible with "BindingList" collections? If I use BusinessBindingListBase in what UIs will it fully work? As you said it will not fully work with WPF (probable Silverligth is the same). I'm not sure but I've read somewhere that ASP.NET should be OK, isn't it?

2) What do you propose to do, if I want to use CSLA for WinForms in WPF (maybe Silverlight) and also in ASP.NET (for sure). How should I design my business objects? I know it's probably hard question, but you should have the best experience to answer this.

Thank you.

RockfordLhotka replied on Friday, May 20, 2011

This is covered quite thoroughly in the Using CSLA 4: Creating Business Objects ebook starting on page 78.

For example, Table 16 lists every interface technology, and the base collection types (ObservableCollection or BindingList) that work with that interface technology.

 

Miroslav Galajda replied on Tuesday, May 24, 2011

Hi, after reading that chapter, I don't know if I'm smart enough.

After all, it seems to me that the only way to go is to use conditionals, similar to what you have used for SILVERLIGHT, e.g.

#if WINFORMS

// use BusinessBindingListBase

#else

// for everything other than windows forms use BusinessListBase

#endif

And to have two build versions of the same business classes (when targeting WinForms and the others).
But if I see how targeting the silverlight version is recommeded it seems that for the silverlight (or WP7) I must have another build.
But here I'm in doubts. To have same name for assemblies and organize them in subfolders or to distinguish them by name and keep in the one folder for all dependencies?

I haven't read the whole ebook series yet. But I want to quickly ask what should I do at first? Do you recommend to create own CSLA derivate for base classes, which will be directly used in my business layers?
But things get little bit complicated. That derivate should have the same number of CSLA derivate builds as the original one, shouldn't it? And finally my business layers should have also have also so many builds as needed by the target UI platforms.

Please, I need clarification.
Thanks

RockfordLhotka replied on Wednesday, May 25, 2011

That is an interesting and unusual perspective.

I have been posting in this thread under the assumption that you have existing WinForms code, and need to migrate to WPF over time. That is the common scenario. Although a little challenging, by supporting OC and BL collections, CSLA 4 makes it possible to do this migration.

It sounds like you are intentionally going to write a new WinForms app? And a WPF app over the same business layer?

Why would you ever do such a thing? It is hard to imagine how you could cost-justify creating two apps that both target Windows and (presumably) provide the same functionality?

Miroslav Galajda replied on Wednesday, May 25, 2011

No, you didn't understand me well.

I'm going to build new business layer which must be used in an existing WinForms application, because this is what we have and we can provide almost instantly to customer.

But in parallel with legacy WinForm application we want to build new applications based on WPF/Silverlight or ASP.NET or combination ASP.NET with Silverlight.

And somewhere in the future to be cut off from the WinForms UI.

I'm just thinking about the way how to do the both and not to fight with technologies.

That's why I'm asking in such way.

Thanks

RockfordLhotka replied on Wednesday, May 25, 2011

Thank you for the clarification.

In that case, where the business layer will be used by WinForms or WPF, but never at the same time (by a hybrid app), I think your idea of using a compiler directive is probably good.

As much as possible, we made BusinessListBase code-compatible with the old version (now called BusinessBindingListBase). For example, BLB supports the AddNewCore overload concepts from BindingList, even though that has no meaning in the OC world. Because other parts of CSLA use it, there's still value in implementing it - but more importantly, we enabled the same code to work, with just the base type being changed.

That isn't always the case. For example, if you manually raise changed events, BLB uses OnCollectionChanged and BBLB uses OnListChanged - and there's not a lot we can do about that, because the events aren't the same.

But most business code doesn't do fancy stuff, and so most business collection classes can switch between the BLB and BBLB base classes with very little code difference. That means the compiler directive approach should be fine.

Miroslav Galajda replied on Thursday, May 26, 2011

Hi, I've just tested if I could bind BusinessListBase to WinForms DataGridView and some other 3rd party GridControl.

At first sight binding just works. Also I can wrap it with SortedBindingList to provide sorting in grid.

Also I've tried BusinessBindingListBase, and found no different behavior between the two lists.

I'm using CSLA 4.1.

Another interesting point is that ReadOnlyListBase is able to accept adding items into it without clearing IsReadOnly flag but ReadOnlyBindingListBase doesn't.

 

RockfordLhotka replied on Thursday, May 26, 2011

Miroslav Galajda

Another interesting point is that ReadOnlyListBase is able to accept adding items into it without clearing IsReadOnly flag but ReadOnlyBindingListBase doesn't.

 

This is a perfect example that demonstrates how several features of BindingList don't exist in ObservableCollection. The whole concept of allowing edit/remove/add to a list is a BindingList feature. Because OC doesn't implement this feature, WinForms treats the collection as though all the options are true - except for add.

In the case of add, BindingList has AddNew and OC does not. So auto-adding of an item in an OC requires that the child type have a public default constructor, and you can't override the use of that constructor (no use of data portal Create to initialize the child).

Miroslav Galajda replied on Thursday, May 26, 2011

This is what I'm looking for. What all features will not work if I bind BLB to WinForm or what features do I need to add manually.

Because the first try I made is just working fine.

RockfordLhotka replied on Thursday, May 26, 2011

I have not worked with WinForms for several years, and I don't remember the full list of missing features. You will have to experiment to see what doesn't work.

JonnyBee replied on Thursday, May 26, 2011

I would expect a number of issues lurking in the shadows.

SortedBindingList and FilteredBindingList support adding/deleting/editing rows in the underlying list. I would expect these to fail at updating the UI or  DatagridViews properly as the event they attach to is the ListChangedEvent from BindingList.

Ex:

    public FilteredBindingList(IList<T> list)
    {
      _list = list;

      if (_list is IBindingList)
      {
        _supportsBinding = true;
        _bindingList = (IBindingList)_list;
        _bindingList.ListChanged +=
          new ListChangedEventHandler(SourceChanged);
      }

    }

 

    public SortedBindingList(IList<T> list)
    {
      _list = list;

      if (_list is IBindingList)
      {
        _supportsBinding = true;
        _bindingList = (IBindingList)_list;
        _bindingList.ListChanged +=
          new ListChangedEventHandler(SourceChanged);
      }

    }

 

RockfordLhotka replied on Thursday, May 26, 2011

Starting in .NET 2.0, Microsoft worked to make some common scenarios work against non-BindingList collections. You might be able to search MSDN or blogs to find some article that describes what they did to support collections that don't actively participate in binding.

Probably searching for "binding a collection to windows forms" will return some useful results.

Think about it this way: Windows Forms is designed to work with BindingList collections. They did what they could to support "dumber" collection types. ObservableCollection is a "dumber" collection type (from a Windows Forms perspective), so any limits discussed in blogs and articles from 2005 apply today as well.

Miroslav Galajda replied on Thursday, May 26, 2011

OK, thank you. I will try to fight against them. :-)

One thing I'm scared about is too complicated model of multiple builds of libraries.

Do you recommend to create own layer (derived CSLA base classes) bon top of CSLA and use that layer as base "CSLA" layer, don't you?

This will result into following model of libraries, won't it?

Client\CSLADerived.dll

Silverlight\CSLADerived.dll

Server\CSLADerived.dll

...?

 

RockfordLhotka replied on Friday, May 27, 2011

Tiago Freitas Leal

Besides sharing the experience, I think this also raises a point. If we must use BusinessBindingListBase for Windows Forms and BusinessListBase for WPF/Silverlight, suppose my application has both clients. I need to have duplicated Business*ListBase classes?

Yes, if you have one business DLL that is used by Windows Forms and WPF UI elements in the same app, then you probably have to create duplicated collection classes.

In my observation, this normally happens when an org has a Windows Forms app, and they migrate to WPF over a period of months or years. So the same app is running some WinForms and some WPF, often using Microsoft's interop capabilities.

My recommendation is to port logical units of functionality from WinForms to WPF, one unit at a time. This way you can port a number of forms to WPF, and can port the related business types as well.

This won't eliminate the need for some duplicate collection types, but it can help reduce the number of duplicates.

The real key is to minimize the number of duplicated editable list types. Read-only lists that subclass ReadOnlyListBase usually work fine in WinForms, because none of the "missing" features are used against a read-only list. Only editable lists are problematic.

Copyright (c) Marimer LLC