Easy way to suppress ListChangeEvents within Lists

Easy way to suppress ListChangeEvents within Lists

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


alex.enjoy posted on Wednesday, April 18, 2012

Hi,

instead of:
var rlce = RaiseListChangedEvents;
RaiseListChangedEvents = false;
        while (data.Read())
          Add(DataPortal.FetchChild<OrderLineItem>(data));
RaiseListChangedEvents = rlce;

you can write:
using(SuppressListChangedEvents.On(this))
 while (data.Read()) 
    Add(DataPortal.FetchChild<OrderLineItem>(data));

similar to using(BypassPropertyChecks)
when you add the following code to a base class inheriting the CSLA list classes:

/// <summary>
/// use it within a using() block
///
</summary>
protected class SuppressListChangedEvents : IDisposable
{
  private readonly ObservableBindingList<TBusinessObject> businessObject;
  private readonly bool initialRaiseListChangedEvents;

  public static SuppressListChangedEvents On(ObservableBindingList<TBusinessObject> businessObject)
  {
   
return new SuppressListChangedEvents(businessObject);
  }

  private
SuppressListChangedEvents(ObservableBindingList<TBusinessObject> businessObject)
  {
    this.businessObject = businessObject;
    initialRaiseListChangedEvents = businessObject.RaiseListChangedEvents;
    businessObject.RaiseListChangedEvents =
false;
  }

  public
void Dispose()
  {
    businessObject.RaiseListChangedEvents = initialRaiseListChangedEvents;
  }
}

bniemyjski replied on Wednesday, April 18, 2012

I like this change, have you written any unit tests for this?

alex.enjoy replied on Wednesday, April 18, 2012

Blake Niemyjski

I like this change, have you written any unit tests for this?

No, I have not. I have my own CSLA base classes subclassing the CSLA base classes.
Within them I implemented this feature.
But I've optimized the code a little bit to be more conform to the already existing BypassPropertyChecks feature.
And to re-use the implementation between different list types I've extracted the class to an internal one.
Now you can simply use it as using(SuppressListChangedEvents) {}

 

 

 

[

Serializable]
public abstract class MyBusinessListBase<TList, TBusinessObject> : BusinessListBase<TList, TBusinessObject>
 
where TList : BusinessListBase<TList, TBusinessObject>
 
where TBusinessObject : IEditableBusinessObject
{
    /// <summary>
   
/// use it within a using() block
   
/// </summary>
   
protected IDisposable SuppressListChangedEvents { get { return new SuppressListChangedEvents<TBusinessObject>(this); } 
}

 

Serializable]
public abstract class MyBusinessListBase<TList, TBusinessObject> : BusinessListBase<TList, TBusinessObject>
 
where TList : BusinessListBase<TList, TBusinessObject>
 
where TBusinessObject : IEditableBusinessObject
{
    /// <summary>
   
/// use it within a using() block
   
/// </summary>
   
protected IDisposable SuppressListChangedEvents { get { return new SuppressListChangedEvents<TBusinessObject>(this); } 
}

 

Serializable]
public abstract class MyBusinessListBase<TList, TBusinessObject> : BusinessListBase<TList, TBusinessObject>
 
where TList : BusinessListBase<TList, TBusinessObject>
 
where TBusinessObject : IEditableBusinessObject
{
    /// <summary>
   
/// use it within a using() block
   
/// </summary>
   
protected IDisposable SuppressListChangedEvents { get { return new SuppressListChangedEvents<TBusinessObject>(this); } 
}

/// <summary>
/// Handles the suppressing of raising ChangedEvents when altering the content of an ObservableBindingList.
/// Will be instanciated by a factory property on the ObservableBindingList implementation.
/// </summary>
/// <typeparam name="TBusinessObject">Type of the BusinessObjects managed by the ObservableBindingList.</typeparam>
internal class SuppressListChangedEvents<TBusinessObject> : IDisposable
{
  private readonly ObservableBindingList<TBusinessObject> businessObject;
  private readonly bool initialRaiseListChangedEvents;

 
public SuppressListChangedEvents(ObservableBindingList<TBusinessObject> businessObject)
  {
   
this.businessObject = businessObject;
    initialRaiseListChangedEvents = businessObject.RaiseListChangedEvents;
    businessObject.RaiseListChangedEvents =
false;
  }

 
public void Dispose()
  {
    businessObject.RaiseListChangedEvents = initialRaiseListChangedEvents;
  }
}

alex.enjoy replied on Thursday, April 19, 2012

Blake Niemyjski

I like this change, have you written any unit tests for this?

I do not know why, but the syntax coloring completely destroyed the layout of my posting.
So here without colors, but correct :-)
(Maybe the Serializable Tag is misinterpreted as BB-Code by the forum?)

No, I have not. I have my own CSLA base classes subclassing the CSLA base classes.
Within them I implemented this feature.
But I've optimized the code a little bit to be more conform to the already existing BypassPropertyChecks feature.
And to re-use the implementation between different list types I've extracted the class to an internal one.
Now you can simply use it as using(SuppressListChangedEvents) {}

 

[Serializable]
public abstract class MyBusinessListBase<TList, TBusinessObject> : BusinessListBase<TList, TBusinessObject>
  where TList : BusinessListBase<TList, TBusinessObject>
  where TBusinessObject : IEditableBusinessObject
{
    /// <summary>
    /// use it within a using() block
    /// </summary>
    protected IDisposable SuppressListChangedEvents { get { return new SuppressListChangedEvents<TBusinessObject>(this); }
}


/// <summary>
/// Handles the suppressing of raising ChangedEvents when altering the content of an ObservableBindingList.
/// Will be instanciated by a factory property on the ObservableBindingList implementation.
/// </summary>
/// <typeparam name="TBusinessObject">Type of the BusinessObjects managed by the ObservableBindingList.</typeparam>
internal class SuppressListChangedEvents<TBusinessObject> : IDisposable
{
  private readonly ObservableBindingList<TBusinessObject> businessObject;
  private readonly bool initialRaiseListChangedEvents;

  public SuppressListChangedEvents(ObservableBindingList<TBusinessObject> businessObject)
  {
    this.businessObject = businessObject;
    initialRaiseListChangedEvents = businessObject.RaiseListChangedEvents;
    businessObject.RaiseListChangedEvents = false;
  }

  public void Dispose()
  {
    businessObject.RaiseListChangedEvents = initialRaiseListChangedEvents;
  }
}

JonnyBee replied on Thursday, April 19, 2012

If you add this code to csla base classes then:

Core\ExtendedBindingList.cs:

    protected IDisposable SuppressListChangedEvents
    {
      get { return new SuppressListChangedEventsClass<T>(this); }
    }
 
    /// <summary>
    /// Handles the suppressing of raising ChangedEvents when altering the content of an ObservableBindingList.
    /// Will be instanciated by a factory property on the ObservableBindingList implementation.
    /// </summary>
    /// <typeparam name="TC">The type of the C.</typeparam>
    class SuppressListChangedEventsClass<TC> : IDisposable
    {
      private readonly BindingList<TC> _businessObject;
      private readonly bool _initialRaiseListChangedEvents;
 
      public SuppressListChangedEventsClass(BindingList<TC> businessObject)
      {
        this._businessObject = businessObject;
        _initialRaiseListChangedEvents = businessObject.RaiseListChangedEvents;
        businessObject.RaiseListChangedEvents = false;
      }
 
      public void Dispose()
      {
        _businessObject.RaiseListChangedEvents = _initialRaiseListChangedEvents;
      }
    }

Core.ObservableBindingList
    protected IDisposable SuppressListChangedEvents
    {
      get { return new SuppressListChangedEventsClass<T>(this); }
    }
 
    /// <summary>
    /// Handles the suppressing of raising ChangedEvents when altering the content of an ObservableBindingList.
    /// Will be instanciated by a factory property on the ObservableBindingList implementation.
    /// </summary>
    /// <typeparam name="TC">The type of the C.</typeparam>
    class SuppressListChangedEventsClass<TC> : IDisposable
    {
      private readonly BindingList<TC> _businessObject;
      private readonly bool _initialRaiseListChangedEvents;
 
      public SuppressListChangedEventsClass(BindingList<TC> businessObject)
      {
        this._businessObject = businessObject;
        _initialRaiseListChangedEvents = businessObject.RaiseListChangedEvents;
        businessObject.RaiseListChangedEvents = false;
      }
 
      public void Dispose()
      {
        _businessObject.RaiseListChangedEvents = _initialRaiseListChangedEvents;
      }
    }

then you can use this code in all list types / <BO> lists. 

Looks good. 

Added to bugtracker: http://www.lhotka.net/cslabugs/edit_bug.aspx?id=1044

Copyright (c) Marimer LLC