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