public UITableViewSource ParseView(DialogViewController controller, object view)
{
var members = view.GetType().GetMembers(false);
var sections = new SortedList<int, Section>();
var memberLists = new SortedList<int, SortedList<int, MemberData>>();
var sectionIndex = 0;
var memberOrder = 0;
foreach (var member in members)
{
var attributes = member.GetCustomAttributes(false);
var memberData = new MemberData(view, member) { Section = sectionIndex };
var defaultValueAttribute = member.GetCustomAttribute<DefaultValueAttribute>();
if (defaultValueAttribute != null)
{
memberData.Value = defaultValueAttribute.Value;
}
var pullToRefreshAttribute = member.GetCustomAttribute<PullToRefreshAttribute>();
if (pullToRefreshAttribute != null)
{
((DialogViewController)controller).PullToRefreshCommand = GetCommandForMember(view, member);
((DialogViewController)controller).RefreshKey = pullToRefreshAttribute.SettingsKey;
((DialogViewController)controller).EnablePullToRefresh = true;
}
var toolbarButtonAttribute = member.GetCustomAttribute<ToolbarButtonAttribute>();
var navbarButtonAttribute = member.GetCustomAttribute<NavbarButtonAttribute>();
var skipAttribute = member.GetCustomAttribute<SkipAttribute>();
if (skipAttribute != null ||
toolbarButtonAttribute != null ||
navbarButtonAttribute != null ||
pullToRefreshAttribute != null ||
(attributes.Length == 0 && typeof(MethodInfo) == memberData.Type))
{
memberData.Dispose();
continue;
}
var themeAttribute = member.GetCustomAttribute<ThemeAttribute>();
if (themeAttribute != null)
{
var theme = Theme.CreateTheme(themeAttribute.ThemeType);
if (theme != null && theme.CellHeight > 0)
{
memberData.RowHeight = theme.CellHeight;
theme.Dispose();
}
}
else
{
var themeable = view as IThemeable;
if (themeable != null && themeable.Theme != null && themeable.Theme.CellHeight > 0)
{
memberData.RowHeight = themeable.Theme.CellHeight;
}
}
var rowHeightAttribute = member.GetCustomAttribute<RowHeightAttribute>();
if (rowHeightAttribute != null)
memberData.RowHeight = rowHeightAttribute.RowHeight;
var listAttribute = member.GetCustomAttribute<ListAttribute>();
var isList = (listAttribute != null && listAttribute.DisplayMode == DisplayMode.List) &&
!typeof(string).IsAssignableFrom(memberData.Type) &&
(typeof(IEnumerable).IsAssignableFrom(memberData.Type) ||
typeof(Enum).IsAssignableFrom(memberData.Type));
var orderAttribute = member.GetCustomAttribute<OrderAttribute>();
if (orderAttribute != null)
{
// make sure assigned order is an even number to fit in between the default order
// allowing the values int.MinValue and int.MaxValue for the first and Last positions
memberData.Order = orderAttribute.Order > int.MaxValue / 2 ? int.MaxValue : orderAttribute.Order * 2;
}
else
{
// make sure all default memberOrder is odd;
memberOrder = memberOrder + (memberOrder % 2) + 1;
memberData.Order = memberOrder;
}
var sectionAttribute = member.GetCustomAttribute<SectionAttribute>();
if (sectionAttribute != null || isList)
{
if (sections.Count > 0)
{
sectionIndex++;
}
memberData.Section = sectionIndex;
if (sectionAttribute != null && orderAttribute != null)
{
memberData.Section = orderAttribute.Order == 0 ? sectionIndex : orderAttribute.Order;
}
else
{
memberData.Section = sectionIndex;
}
}
var viewTypes = GetViewTypes(memberData);
if (!sections.ContainsKey(memberData.Section))
{
var section = CreateSection(controller, memberData, viewTypes);
sections.Add(memberData.Section, section);
}
else
{
if (viewTypes != null)
{
IList<Type> list = null;
var key = memberData.Id.ToString();
var viewTypesList = sections[memberData.Section].ViewTypes;
if (viewTypesList.ContainsKey(key))
{
list = viewTypesList[key];
}
else
{
list = new List<Type>();
viewTypesList.Add(key, list);
}
foreach(var viewType in viewTypes)
{
if (!list.Contains(viewType))
{
list.Add(viewType);
}
}
}
}
if (memberLists.ContainsKey(memberData.Section))
{
memberLists[memberData.Section].Add(memberData.Order, memberData);
}
else
{
var sortedList = new SortedList<int, MemberData>();
sortedList.Add(memberData.Order, memberData);
memberLists.Add(memberData.Section, sortedList);
}
}
foreach(var kvp in memberLists)
{
var listSources = new SortedList<int, ListSource>();
var index = 0;
var list = kvp.Value.Values.ToList();
list.ForEach(data => data.Order = index++);
foreach(var memberData in list)
{
var viewTypes = GetViewTypes(memberData);
if ((!typeof(string).IsAssignableFrom(memberData.Type) && typeof(IEnumerable).IsAssignableFrom(memberData.Type)) || typeof(Enum).IsAssignableFrom(memberData.Type))
{
var listSource = ParseList(controller, memberData, viewTypes) as ListSource;
listSource.MemberData = memberData;
listSource.Sections[0].Index = memberData.Section;
listSources.Add(memberData.Order, listSource);
}
else
listSources.Add(memberData.Order, null);
sections[memberData.Section].ListSources = listSources;
sections[memberData.Section].Index = memberData.Section;
var lastListSource = listSources.Values.Last();
if (lastListSource != null)
memberData.DataContextBinder = new DataContextBinder(controller, lastListSource.Sections[0]);
}
sections[kvp.Key].DataContext = list;
}
var keyIndex = 0;
var sectionList = sections.Select(kvp => kvp.Value).ToDictionary((value) => keyIndex++);
// If there is only one list property return the ListSource rather than create a ViewSource
if (sectionList.Count == 1 && sectionList[0].DataContext.Count == 1 && sectionList[0].ListSources[0] != null && !sectionList[0].ListSources[0].IsRootCell)
{
sectionList[0].ListSources[0].TableViewStyle = UITableViewStyle.Plain;
return sectionList[0].ListSources[0];
}
var source = new ViewSource(controller) { Sections = sectionList };
return source;
}