Skip to content

Instantly share code, notes, and snippets.

@jakesays-old
Created December 9, 2017 04:26
Show Gist options
  • Save jakesays-old/daf8de5d201e8090a3591fe619edd181 to your computer and use it in GitHub Desktop.
Save jakesays-old/daf8de5d201e8090a3591fe619edd181 to your computer and use it in GitHub Desktop.
using System;
using System.Collections.Generic;
using System.ComponentModel;
namespace Std.BasicTypes
{
[Serializable]
public class PropertyTrackingManager : INotifyPropertyChanged
{
private object _eventSender;
private string[] _propertyNames;
public event PropertyChangedEventHandler PropertyChanged;
public int PropertyCount { get; private set; }
public StateVector State { get; private set; }
public bool BatchUpdating { get; private set; }
public PropertyTrackingManager(string[] propertyNames, object eventSender = null)
{
Initialize(propertyNames, eventSender);
}
protected void Initialize(string[] propertyNames, object eventSender)
{
_eventSender = eventSender;
PropertyCount = propertyNames.Length;
State = new StateVector(PropertyCount);
_propertyNames = propertyNames;
}
protected PropertyTrackingManager()
{
}
public void BeginUpdate()
{
State.SetAll(false);
BatchUpdating = true;
}
public int ChangedPropertyCount
{
get => State.SetBitCount;
}
public IEnumerable<string> GetChangedProperties()
{
foreach (var propId in State.GetSetIndexes())
{
yield return _propertyNames[propId];
}
}
public int EndUpdate(bool notifyAll = false)
{
if (!BatchUpdating)
{
return 0;
}
BatchUpdating = false;
var count = State.SetBitCount;
if (notifyAll)
{
NotifyOfChanges();
}
return count;
}
public void NotifyOfChanges()
{
if (_eventSender == null ||
PropertyChanged?.GetInvocationList()
.Length == 0)
{
return;
}
foreach (var property in GetChangedProperties())
{
PropertyChanged?.Invoke(_eventSender, new PropertyChangedEventArgs(property));
}
}
public void NotifyOfPropertyChange(string propertyName)
{
PropertyChanged?.Invoke(_eventSender, new PropertyChangedEventArgs(propertyName));
}
public void ClearState(int propertyId, bool notify = false)
{
State.Set(propertyId, false);
if (BatchUpdating)
{
return;
}
if (!notify)
{
return;
}
if (_eventSender == null ||
PropertyChanged?.GetInvocationList().Length == 0)
{
return;
}
var property = _propertyNames[propertyId];
PropertyChanged?.Invoke(_eventSender, new PropertyChangedEventArgs(property));
}
public void SetState(int propertyId)
{
if (BatchUpdating)
{
State.Set(propertyId, true);
return;
}
if (_eventSender == null ||
PropertyChanged?.GetInvocationList()
.Length == 0)
{
return;
}
var property = _propertyNames[propertyId];
PropertyChanged?.Invoke(_eventSender, new PropertyChangedEventArgs(property));
}
}
}
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment