Implementing IParentYou may implement your own Parents and related Extension classes. I recommend merely following the pattern set in the existing Parents and Extensions?
Here is the IParent interface and optional interfaces ICanGenerate, ICanSelect, ICanSort, and ICanFilter:
/// <summary>
/// Implemented on any class that supports adding or removing Composites
/// </summary>
public interface IParent
{
//A composite is added by key and args
object Add<T>(object chain, string key, T args, System.Windows.Controls.Border itemToBind);
void Remove(object chain, string key, Border itemToRemove);
List<Border> RetrieveCollection(object chain);
Dictionary<string, object> RetrieveDictionary(object chain);
}
public interface ICanGenerate
{
object Generate<T>(object chain, T args, Action<System.Windows.Controls.StackPanel> addUIElementsAction);
}
public interface ICanSelect
{
void SetSelected(object chain, System.Windows.Controls.Border itemToSetAsSelected);
}
public interface ICanSort
{
void ClearCollection(object chain);
void BeforeSortCollection<T>(object chain, object args, int row, int column, FasterWPF.CommonExt.SortOrder sortOrder, CommonExt.SortControlType sortControlType)
where T : FrameworkElement;
void BeforeSortCollection1Then2<T>(object chain, object args, int row, int column, int row2, int column2, FasterWPF.CommonExt.SortOrder sortOrder, FasterWPF.CommonExt.SortOrder sortOrder2, CommonExt.SortControlType sortControlType)
where T : FrameworkElement;
void AfterSortCollection<T>(object chain)
where T : FrameworkElement;
}
public interface ICanFilter
{
T FilterByText<T>(T chain, int row, int column, Predicate<string> filterPredicate)
where T : FrameworkElement;
T FilterByText1And2<T>(T chain, int row, int column, int row2, int column2, Predicate<Tuple<string, string>> filterPredicate)
where T : FrameworkElement;
T FilterByText1And2And3<T>(T chain, int row, int column, int row2, int column2, int row3, int column3, Predicate<Tuple<string, string, string>> filterPredicate)
where T : FrameworkElement;
}
Here is the
WrapPanelParent as an example:
NOTE: parents need to implement there own Args and may optionally implement their own ISortArgs.
public class WrapPanelSort : FasterWPF.CommonExt.ISortArgs
{
public WrapPanelSort(CommonExt.SortDataType sortDataType)
{
SortDataType = sortDataType;
}
public WrapPanelSort(CommonExt.SortDataType sortDataType, CommonExt.SortDataType sortDataType2)
{
SortDataType = sortDataType;
SortDataType2 = sortDataType2;
}
public CommonExt.SortDataType SortDataType
{
get;
set;
}
public CommonExt.SortDataType SortDataType2
{
get;
set;
}
}
public class WrapPanelArgs
{
public Orientation Orientation { get; set; }
public WrapPanelArgs(Orientation orientation)
{
Orientation = orientation;
}
}
public class WrapPanelParent : FasterWPF.IParent, ICanSort
{
public object Generate<T>(object chain, T args, Action<WrapPanel> addUIElementsAction)
{
return chain;
}
public object Add<T>(object chain, string key, T args, Border itemToAdd)
{
if (args is WrapPanelArgs)
{
if ((args as WrapPanelArgs).Orientation != null)
{
((WrapPanel)chain).Orientation = (args as WrapPanelArgs).Orientation;
}
}
((WrapPanel)chain).Children.Add(itemToAdd);
return chain;
}
public void Remove(object chain, string key, Border itemToRemove)
{
((WrapPanel)chain).Children.Remove(itemToRemove); //remove from Window
IComposite ic = (IComposite)(((WrapPanel)chain).GetIComposite<WrapPanel>());
ic.RemoveFromChain(itemToRemove);
}
public Dictionary<string, object> RetrieveDictionary(object chain)
{
return ((WrapPanel)chain).GetCompositeLookupDictionary<WrapPanel>();
}
public List<Border> RetrieveCollection(object chain)
{
List<Border> lb = new List<Border>();
foreach (var kvp in ((WrapPanel)chain).GetCompositeLookupDictionary<WrapPanel>())
{
lb.Add((Border)kvp.Value);
}
return lb;
}
public void ClearCollection(object chain)
{
IParent currentComposite = ((WrapPanel)chain).GetSetting<WrapPanel, IParent>("IParent");
List<Border> gridItems = currentComposite.RetrieveCollection(chain);
foreach (Border borItem in gridItems)
{
((WrapPanel)chain).Children.Remove(borItem); //remove from WrapPanel
}
}
public void BeforeSortCollection<T>(object chain, object args, int row, int column, CommonExt.SortOrder sortOrder, CommonExt.SortControlType sortControlType)
where T : FrameworkElement
{
var orderedKeys = ((WrapPanel)chain).GetOrderedKeyList();
var rows = ((WrapPanel)chain).GetCompositeLookupDictionary();
Dictionary<string, object> ChildLookupDict = ((WrapPanel)chain).GetChildLookupDictionary();
IParent currentComposite = ((WrapPanel)chain).GetSetting<WrapPanel, IParent>("IParent");
List<Border> gridItemsUnOrdered = currentComposite.RetrieveCollection(chain);
List<Border> gridItems = new List<Border>();
foreach (string s in orderedKeys)
{
gridItems.Add(gridItemsUnOrdered.Where(b => { return b.GetKey() == s; }).First());
}
List<int> initialOrderCol = new List<int>();
List<int> initialOrderRow = new List<int>();
List<string> initialOrderKey = new List<string>();
foreach (Border borK in gridItems)
{
initialOrderKey.Add(borK.GetKey());
}
if (gridItems != null && gridItems.Count > 0)
{
ClearCollection(chain);
orderedKeys.Clear();
IEnumerable<string> items = null;
if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.DateTime)
{
items = CommonInternalExt.PerformSortOfKeysLevelOneDateTime<T>(row, column, sortOrder, ChildLookupDict, items, sortControlType);
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.Decimal)
{
items = CommonInternalExt.PerformSortOfKeysLevelOneDecimal<T>(row, column, sortOrder, ChildLookupDict, items, sortControlType);
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.Integer)
{
items = CommonInternalExt.PerformSortOfKeysLevelOneInteger<T>(row, column, sortOrder, ChildLookupDict, items, sortControlType);
}
else
{
//Default to String
items = CommonInternalExt.PerformSortOfKeysLevelOne<T>(row, column, sortOrder, ChildLookupDict, items, sortControlType);
}
List<string> itemsToList = items.ToList();
IterHelpers.ApplyLoop(itemsToList.Count, j =>
{
String tempKey = (string)itemsToList[j];
Border tempBorder = gridItems[initialOrderKey.FindIndex(str => { return str == tempKey; })];
orderedKeys.Add(tempKey);
((WrapPanel)chain).Children.Add(tempBorder);
});
}
}
public void BeforeSortCollection1Then2<T>(object chain, object args, int row, int column, int row2, int column2, CommonExt.SortOrder sortOrder, CommonExt.SortOrder sortOrder2, CommonExt.SortControlType sortControlType) where T : FrameworkElement
{
var orderedKeys = ((T)chain).GetOrderedKeyList();
var rows = ((T)chain).GetCompositeLookupDictionary();
Dictionary<string, object> ChildLookupDict = ((T)chain).GetChildLookupDictionary();
IParent currentComposite = ((T)chain).GetSetting<T, IParent>("IParent");
List<Border> gridItemsUnOrdered = currentComposite.RetrieveCollection(chain);
List<Border> gridItems = new List<Border>();
foreach (string s in orderedKeys)
{
gridItems.Add(gridItemsUnOrdered.Where(b => { return b.GetKey() == s; }).First());
}
List<string> initialOrderKey = new List<string>();
foreach (Border borK in gridItems)
{
initialOrderKey.Add(borK.GetKey());
}
if (gridItems != null && gridItems.Count > 0)
{
ClearCollection(chain);
Dictionary<string, Tuple<object, object>> sourceToSortOn = new Dictionary<string, Tuple<object, object>>();
string defaultNullValue = null;
string defaultNullValue2 = null;
if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.DateTime)
{
defaultNullValue = "1/1/1900";
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.Decimal)
{
defaultNullValue = "0.00";
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.Integer)
{
defaultNullValue = "0";
}
else
{
defaultNullValue = "";
}
if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType2) == FasterWPF.CommonExt.SortDataType.DateTime)
{
defaultNullValue2 = "1/1/1900";
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType2) == FasterWPF.CommonExt.SortDataType.Decimal)
{
defaultNullValue2 = "0.00";
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType2) == FasterWPF.CommonExt.SortDataType.Integer)
{
defaultNullValue2 = "0";
}
else
{
defaultNullValue2 = "";
}
CommonInternalExt.SetDefaultsForTextElementsAtRowCol<T>(chain, row, column, row2, column2, sortControlType, orderedKeys, sourceToSortOn, defaultNullValue, defaultNullValue2);
orderedKeys.Clear();
IOrderedEnumerable<KeyValuePair<string, Tuple<object, object>>> items = null;
Type dataType1 = null;
Type dataType2 = null;
if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.DateTime)
{
dataType1 = typeof(DateTime);
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.Decimal)
{
dataType1 = typeof(Decimal);
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType) == FasterWPF.CommonExt.SortDataType.Integer)
{
dataType1 = typeof(Int32);
}
else
{
dataType1 = typeof(String);
}
if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType2) == FasterWPF.CommonExt.SortDataType.DateTime)
{
dataType2 = typeof(DateTime);
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType2) == FasterWPF.CommonExt.SortDataType.Decimal)
{
dataType2 = typeof(Decimal);
}
else if (args is FasterWPF.CommonExt.ISortArgs && (((FasterWPF.CommonExt.ISortArgs)args).SortDataType2) == FasterWPF.CommonExt.SortDataType.Integer)
{
dataType2 = typeof(Int32);
}
else
{
dataType2 = typeof(String);
}
items = CommonInternalExt.PerformSortOfKeysLevelTwo(chain, sortOrder, sortOrder2, sourceToSortOn, items, dataType1, dataType2);
List<KeyValuePair<string, Tuple<object, object>>> itemsToList = items.ToList();
IterHelpers.ApplyLoop(itemsToList.Count, j =>
{
String tempKey = ((KeyValuePair<string, Tuple<object, object>>)itemsToList[j]).Key.ToString();
Border tempBorder = gridItems[initialOrderKey.FindIndex(str => { return str == tempKey; })];
orderedKeys.Add(tempKey);
((WrapPanel)chain).Children.Add(tempBorder);
//Grid.SetColumn(tempBorder, initialOrderCol[j]);
//Grid.SetRow(tempBorder, initialOrderRow[j]);
});
}
}
public void AfterSortCollection<T>(object chain)
where T : FrameworkElement
{ }
public void InnerSortCollection(object chain, int row, int column, string key, ref int counter, Border itemToReAdd)
{
throw new NotImplementedException();
}
public void SetSelected(object chain, Border itemToSetAsSelected)
{
}
//public void GetSelected
}
Here is the
WrapPanelExt as a simple example:
public static class WrapPanelExt
{
public static WrapPanel SetBackgroundColor(this WrapPanel chain, Brush brush)
{
Brush newBrush = (brush);
chain.Background = newBrush;
return chain;
}
public static WrapPanel Initialize(this WrapPanel source, double width, double height, ContainerType containerType, double itemHeight, double itemWidth, Orientation orientation, FlowDirection flowDirection)
{
//Force the Aero theme by default to assure the structure of the Listbox
Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);
source.ItemHeight = itemHeight;
source.ItemWidth = itemWidth;
source.FlowDirection = flowDirection;
source.Orientation = orientation;
source.Width = width;
source.Height = height;
sharedWrapPanelInitializeCode(source, containerType);
return source;
}
public static WrapPanel Initialize(this WrapPanel source, double width, double height, ContainerType containerType, Orientation orientation, FlowDirection flowDirection)
{
//Force the Aero theme by default to assure the structure of the Listbox
Uri uri = new Uri("/PresentationFramework.Aero;component/themes/Aero.NormalColor.xaml", UriKind.Relative);
source.Resources.MergedDictionaries.Add(Application.LoadComponent(uri) as ResourceDictionary);
source.FlowDirection = flowDirection;
source.Orientation = orientation;
source.Width = width;
source.Height = height;
sharedWrapPanelInitializeCode(source, containerType);
return source;
}
private static void sharedWrapPanelInitializeCode(WrapPanel source, ContainerType containerType)
{
source.SetContainerType(containerType);
IComposite icomp = CompositeTypeHelper.CreateIComposite<WrapPanel>(source);
source.SetIComposite<WrapPanel>(icomp);
WrapPanelParent gbsr = new WrapPanelParent();
source.StoreSetting<WrapPanel>("IParent", gbsr);
source.AddItemBorder(Brushes.Gray, new Thickness(1, 1, 1, 1)); //default Border
source.StoreSetting<WrapPanel>("BorderSettings", new BorderSettings() { Width = double.NaN, Height = double.NaN, BorderBrush = Brushes.Gray, BorderThickness = new Thickness(0, 0, 0, 0), CornerRadius = new CornerRadius(0), Padding = new Thickness(0) });
}
}//end of class