CanExecuteRemove not working in CslaDataProviderCommandManager in CSLA 4.5

CanExecuteRemove not working in CslaDataProviderCommandManager in CSLA 4.5

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


djdewet posted on Friday, August 30, 2013

I updated a fairly old project to use CSLA 4.5, and suddenly noticed that my Delete buttons linked to the CommandManager of the CslaDataProdiver were not getting enabled when they should.  After downloading the source code and looking at the process in question I realized that the cast in the CanExecuteRemove from BusinessListBase to IBindingList would not work, because the implementation now uses ObservableBindingList and not ExtendedBindingList as previously, and ObservableBindingList  does not implement IBindingList.  So, after looking around a bit more and scratching my head, as to how best to fix it, I came up with 3 changes.  There is probably a more elegant way of implementing this, but this works for me now.  Hopefully it gets fixed in an upcoming release.

 

First change:  (In CslaDataProviderCommandManager class)

private static void CanExecuteRemove(object target, CanExecuteRoutedEventArgs e)
      {
          bool result = false;
          CslaDataProviderCommandManager ctl = target as CslaDataProviderCommandManager;
          if (ctl != null && ctl.Provider != null)
          {
              if (ctl.Provider.Data != null)
              {
                  Csla.Core.BusinessBase bb = e.Parameter as Csla.Core.BusinessBase;
                  IBindingList list;
                  IObservableBindingList list2 = null;
                  if (bb != null)
                  {
                      list = bb.Parent as IBindingList;
                      if (list == null)
                          list2 = bb.Parent as IObservableBindingList;
                  }
                  else
                  {
                      list = ctl.Provider.Data as IBindingList;
                      if (list == null)
                          list2 = ctl.Provider.Data as IObservableBindingList;
                  }
                  if (list != null)
                  {
                      result = list.AllowRemove;
                      if (result &&
                          !Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject,
                                                                  ctl.Provider.Data))
                          result = false;
                  }
                  else if (list2 != null)
                  {
                      result = list2.AllowRemove;
                      if (result &&
                          !Csla.Rules.BusinessRules.HasPermission(Rules.AuthorizationActions.EditObject,
                                                                  ctl.Provider.Data))
                          result = false;
                  }
              }
          }
          e.CanExecute = result;
      }

Second change:  (In CslaDataProvider class)

public void RemoveItem(object sender, ExecuteEventArgs e)
      {
          var item = e.MethodParameter;
          // only do something if the object implements
          // IBindingList
          IBindingList list;
          IObservableBindingList list2 = null;
          IList list3 = null;
          Csla.Core.BusinessBase bb = item as Csla.Core.BusinessBase;
          if (bb != null)
          {
              list = bb.Parent as IBindingList;
              if (list == null)
              {
                  list2 = bb.Parent as IObservableBindingList;
                  list3 = bb.Parent as IList;
              }
          }
          else
          {
              list = this.Data as IBindingList;
              if (list == null)
              {
                  list2 = bb.Parent as IObservableBindingList;
                  list3 = bb.Parent as IList;
              }
          }
          if (list != null && list.AllowRemove)
              list.Remove(item);
          if (list2 != null && list3 != null && list2.AllowRemove)
              list3.Remove(item);
      }

Change 3: (Added the following to IObservableBindingList)

bool AllowNew { get; }
bool AllowEdit { get; }
bool AllowRemove { get; }

Hope this makes sense.

 

David

djdewet replied on Friday, August 30, 2013

Yikes !!!!   Just realized that I have to apply the same sort of changes for CanExecuteNew and associated code.  Am I completely missing the boat here, or is this really a bug ?

 

David

JonnyBee replied on Friday, August 30, 2013

Change your code to use BudinessBindingListBase / ReadOnlyBindingListBase base classes. These are the "old" BindingList base classes. 

The CslaDataProvider is included primarily for support of legacy code. 

djdewet replied on Friday, August 30, 2013

Thanks Jonny, I actually forgot about Rocky's post I read about renaming the classes to keep compatibility.  I should have through about that.  If CslaDataProvider is legacy, then what approach should I use in new code ?

David

JonnyBee replied on Friday, August 30, 2013

For SL and WPF most developers use MVVM frameworks and the CSLA.Xaml.ViewModel or ViewModelBase is a good starting point for creating the VewModel

Copyright (c) Marimer LLC