This is a migrated thread and some comments may be shown as answers.

Set event inside nested datatemplate

0 Answers 83 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Russel
Top achievements
Rank 1
Russel asked on 16 Dec 2012, 04:04 PM
Hello, 
   I'm using DataGridView and design a dynamic grid view with GridViewToggleRowDetailsColumn. so far I can register an event at first level like this:
view.RowDetailsVisibilityChanged += new EventHandler<GridViewRowDetailsEventArgs>(view_RowDetailsVisibilityChanged2);
  my datatemplate look like this
private DataTemplate CreateNewDataTemplate()
        {
            string rtnXaml = string.Empty;
            string baseXaml = @"<DataTemplate x:Key='RowDetailsTemplate'
                    xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                    xmlns:telerik='http://schemas.telerik.com/2008/xaml/presentation'
                    xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
                    <telerik:RadGridView Name='SubListGrid{KEYTYPE}' ItemsSource='{Binding DetailList}' AutoGenerateColumns='False' CanUserSortGroups='False' CanUserInsertRows='False' CanUserFreezeColumns='False' CanUserDeleteRows='False' ShowGroupPanel='False' IsReadOnly='true'>
                        <telerik:RadGridView.Columns>
                            {TOGGLEROWDETAILCOLUMN}
                            <telerik:GridViewDataColumn Header='{HEADER}' DataMemberBinding='{Binding GroupKey}' TextAlignment='Center'/>
                            <telerik:GridViewDataColumn Header='人數' DataMemberBinding='{Binding Count}' TextAlignment='Right' DataFormatString = '{}{0:N0}'/>
                            <telerik:GridViewDataColumn Header='百分比' DataMemberBinding='{Binding Percentage}' DataFormatString = '{}{0:f2}%' TextAlignment='Right'/>
                        </telerik:RadGridView.Columns>
                  {SUBTEMPLATE}
                  </telerik:RadGridView>
                </DataTemplate>";
            string subLevelXaml = @"<telerik:RadGridView.RowDetailsTemplate>
                    <DataTemplate x:Key='RowDetailsTemplate'>
                    <telerik:RadGridView Name='SubListGrid{KEYTYPE}' ItemsSource='{Binding DetailList}' AutoGenerateColumns='False' CanUserSortGroups='False' CanUserInsertRows='False' CanUserFreezeColumns='False' CanUserDeleteRows='False' ShowGroupPanel='False' IsReadOnly='true'>
                        <telerik:RadGridView.Columns>
                            {TOGGLEROWDETAILCOLUMN}
                            <telerik:GridViewDataColumn Header='{HEADER}' DataMemberBinding='{Binding GroupKey}' TextAlignment='Center'/>
                            <telerik:GridViewDataColumn Header='人數' DataMemberBinding='{Binding Count}' TextAlignment='Right' DataFormatString = '{}{0:N0}'/>
                            <telerik:GridViewDataColumn Header='百分比' DataMemberBinding='{Binding Percentage}' DataFormatString = '{}{0:f2}%' TextAlignment='Right'/>
                        </telerik:RadGridView.Columns>
                  {SUBTEMPLATE}
                  </telerik:RadGridView>
                </DataTemplate>
                </telerik:RadGridView.RowDetailsTemplate>";
            foreach (ReportType type in command)
            {
                if (command.First().Equals(type))
                {
                    if (ReportType.Location.Equals(type))
                        rtnXaml = baseXaml.Replace("{KEYTYPE}", "Area").Replace("{HEADER}", "縣/市");
                    continue;
                }
                if (rtnXaml.Equals(string.Empty))
                {
                    rtnXaml = baseXaml.Replace("{KEYTYPE}", type.ToString()).Replace("{HEADER}", HeaderKeyDictionary[type.ToString()].ToString());
                }
                else
                {
                    string subXaml = subLevelXaml.Replace("{KEYTYPE}", type.ToString()).Replace("{HEADER}", HeaderKeyDictionary[type.ToString()].ToString());
                    rtnXaml = rtnXaml.Replace("{TOGGLEROWDETAILCOLUMN}", "<telerik:GridViewToggleRowDetailsColumn/>").Replace("{SUBTEMPLATE}", subXaml);
                }
                if (ReportType.Location.Equals(type))
                {
                    string subXaml = subLevelXaml.Replace("{KEYTYPE}", "Area").Replace("{HEADER}", "縣/市");
                    rtnXaml = rtnXaml.Replace("{TOGGLEROWDETAILCOLUMN}", "<telerik:GridViewToggleRowDetailsColumn/>").Replace("{SUBTEMPLATE}", subXaml);
                }
            }
            rtnXaml = rtnXaml.Replace("{TOGGLEROWDETAILCOLUMN}", string.Empty).Replace("{SUBTEMPLATE}", string.Empty);
            System.Text.UTF8Encoding myEncoder = new System.Text.UTF8Encoding();
            byte[] bytes = myEncoder.GetBytes(rtnXaml);
            MemoryStream ms = new MemoryStream(bytes);
            DataTemplate dt = (DataTemplate)XamlReader.Load(ms);           
            return dt;
        }
   however, the toggle event not fire at the second level. It just can happen in first level. so how can i make it happen if i wish every toggle button can call the registered event at first level?

here is whole cs file.
using System;
using System.Collections;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Threading;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Threading;
using Friendo.Backstage.Base;
using Friendo.Backstage.BusinessWCFReference;
using Friendo.Backstage.Model;
using Friendo.Backstage.Support.Structure;
using Friendo.Backstage.View;
using Microsoft.Practices.EnterpriseLibrary.Caching;
using Telerik.Windows.Controls;
using Telerik.Windows.Controls.Charting;
using Telerik.Windows.Data;
using Telerik.Windows.Controls.GridView;
 
namespace Friendo.Backstage.ViewModel
{
    class MemberAnalysisVM
        : GridMaintenceVM<MemberAnalysisModel, MemberAnalysisDashboard>, IViewModel
    {
        Hashtable HeaderDictionary = new Hashtable();
        Hashtable HeaderKeyDictionary = new Hashtable();
        ICacheManager cacheManager = CacheFactory.GetCacheManager();
        Queue<ReportType> command = new Queue<ReportType>();
        enum ReportType
        {
            None=0,Gender,Age,Area,Location
        }
        class AggregateModel
        {
            public string GroupKey { get; set; }
            public int Count { get; set; }
            public float Percentage { get; set; }           
            public ReportType NextType { get; set; }
            public ArrayList DetailList { get; set; }
        }
        class AreaModel
        {
            public string Area { get; set; }
            public int Count { get; set; }
            public float Percentage { get; set; }
            public List<MemberAnalysisDetailModel> CountriesList { get; set; }
        }
        AuthToken token = AuthToken.GetInstance();
        public MemberAnalysisVM()
        {
            this.Initialize();
        }
        void UpdateMemberCount()
        {
            SetMemberCount();
            UpdateMemberCountRuntime();
        }
        void UpdateMemberCountRuntime()
        {
            DispatcherTimer t = new DispatcherTimer();
            int sleepTime = 60 * 1000 * 1000;
            t.Tick += new EventHandler(t_Tick);
            t.Interval = new TimeSpan(sleepTime);
            t.Start();
        }
        void t_Tick(object sender, EventArgs e)
        {
            SetMemberCount();
        }
 
        private void SetMemberCount()
        {
            using (BusinessWCFReference.BusinessClient client = new BusinessWCFReference.BusinessClient())
            {
                BusinessWCFReference.GetThirdPartyMemberCountsInput input = new BusinessWCFReference.GetThirdPartyMemberCountsInput() { ThirdPartyID = token.ThirdPartyID };
                var output = client.GetThirdPartyMemberCounts(input);
                if (output.IsSuccess)
                {
                    QueryView.MemberCount.Text = output.ReturnData.TotalCounts;
                };
                var rtn = client.GetThirdPartyBasicInfo(new GetThirdPartyBasicInfoInput() { ThirdPartyID = token.ThirdPartyID });
            }
        }
        private void Initialize()
        {
            QueryView.busyr.IsBusy = false;
            if (token == null)
                token = AuthToken.GetInstance();
 
            if (string.IsNullOrEmpty(token.ThirdPartyID))
                return;//       TODO;補登出           
            if (cacheManager.GetData("Report") == null)
            {
                QueryView.busyr.IsBusy = true;
                Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                        new Action(() => GetData()));
            }
            GenerateHeaderDictionary();
            ShowView = new FrameView();
            ShowView.AddView(QueryView);
             
            QueryView.DataContext = this;
            SetActiveView(QueryView);           
            QueryView.Gender.Checked += RadioButtonClick;
            QueryView.Age.Checked += RadioButtonClick;
            QueryView.Location.Checked += RadioButtonClick;
             
            QueryView.GenderButton.Checked += CheckedButton;
            QueryView.AgeButton.Checked += CheckedButton;
            QueryView.LocationButton.Checked += CheckedButton;
            QueryView.GenderButton.Unchecked += GenderButton_Unchecked;
            QueryView.AgeButton.Unchecked += GenderButton_Unchecked;
            QueryView.LocationButton.Unchecked += GenderButton_Unchecked;
 
            QueryView.busyr.Cancel += new EventHandler(busyr_Cancel);
            UpdateMemberCount();
            QueryView.busyr.IsBusy = false;
        }
        private void GenerateNewView()
        {
            if (command.Count <= 1)
            {
                ShowUI(command.FirstOrDefault());
                return;
            }
             
            DataTemplate template = new DataTemplate();
            List<AggregateModel> aggregateList = SortData();
            ReportType firstKey = command.FirstOrDefault();
             
 
            RadGridView view = new RadGridView()
            {
                CanUserSortGroups = false,
                CanUserInsertRows = false,
                CanUserFreezeColumns = false,
                CanUserDeleteRows = false,
                AutoGenerateColumns = false,
                ShowGroupPanel = false,
                ShowColumnFooters = true,
                ShowGroupFooters = true,
                MaxHeight = QueryView.Report.MaxHeight
            };
            view.RowDetailsTemplate = CreateNewDataTemplate();
            view.RowDetailsVisibilityChanged += new EventHandler<GridViewRowDetailsEventArgs>(view_RowDetailsVisibilityChanged2);
            view.Columns.Add(new GridViewToggleRowDetailsColumn());
             
            view.Columns.Add((GridViewDataColumn)HeaderDictionary[firstKey.ToString() + "MultiSelected"]);           
            view.Columns.Add((GridViewDataColumn)HeaderDictionary["Count"]);
            view.Columns.Add((GridViewDataColumn)HeaderDictionary["Percentage"]);
 
            view.ItemTemplate = template;
            view.ItemsSource = aggregateList;
            Dictionary<string, int> dictionary = aggregateList.GroupBy(p => p.GroupKey, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g.First().Count, StringComparer.OrdinalIgnoreCase);
            GeneratePieChart(dictionary);
            QueryView.Report.Children.Clear();
            QueryView.Report.Children.Add(view);
        }
 
        void view_RowDetailsVisibilityChanged2(object sender, GridViewRowDetailsEventArgs e)
        {
             
        }
        void CheckedButton(object sender, RoutedEventArgs e)
        {
            ReportType mykey = (ReportType)Enum.Parse(typeof(ReportType), (string)((CheckBox)e.Source).Name.Replace("Button", string.Empty), true);
            if (!command.Contains(mykey))
                command.Enqueue(mykey);
             
            GenerateNewView();
        }
        void GenderButton_Unchecked(object sender, RoutedEventArgs e)
        {
            ReportType mykey = (ReportType)Enum.Parse(typeof(ReportType), (string)((CheckBox)e.Source).Name.Replace("Button", string.Empty), true);
            Queue<ReportType> newQueue = new Queue<ReportType>();
            foreach (ReportType type in command)
            {
                if (mykey != type)
                    newQueue.Enqueue(type);
            }
            command = newQueue;
 
            GenerateNewView();
        }
        List<AggregateModel> SortData()
        {           
            List<MemberAnalysisDetailModel> list = GetData();
            ReportType nextCommand = (command.Count <= 1) ? ReportType.None : command.ToList()[command.ToList().IndexOf(command.First()) + 1];
            List<AggregateModel> rtnList = new List<AggregateModel>();
            switch (command.First())
            {
                case ReportType.Gender:
                    rtnList = list.GroupBy(w => w.Gender).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                    break;
                case ReportType.Age:
                    rtnList = list.GroupBy(w => w.Age).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                    break;
                case ReportType.Location:
                    rtnList = list.GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                    break;
                default:
                    return new List<AggregateModel>();
            }
            int sum = rtnList.Sum(t => t.Count);
            rtnList.ForEach(t => t.Percentage = (float)t.Count / (float)sum * 100);
 
            ReportType aggregateKey = nextCommand;
            nextCommand = (command.Last().Equals(aggregateKey)) ? ReportType.None : command.ToList()[command.ToList().IndexOf(aggregateKey) + 1];
            foreach (var subList in rtnList)
            {
                List<AggregateModel> sortedAggregateList = new List<AggregateModel>();
                sortedAggregateList = AggregateSublist(aggregateKey, subList.DetailList);
                sum = sortedAggregateList.Sum(t => t.Count);
                sortedAggregateList.ForEach(t => t.Percentage = (float)t.Count / (float)sum * 100);
 
                AggreateSubList(sortedAggregateList);
                subList.DetailList = new ArrayList(sortedAggregateList);
            }
            if(ReportType.Location.Equals(command.First()))
            {
                rtnList = GenerateAreaReportData(rtnList, nextCommand);
            }
            return rtnList;
        }
        List<AggregateModel> AggreateSubList(List<AggregateModel> target)
        {
            foreach (var subList in target)
            {
                if (!((ReportType.None.Equals(subList.NextType))))
                {
                    if ((ReportType.Location.Equals(subList.NextType)) && ((Enum.GetNames(typeof(LocationEnum)).Contains(subList.GroupKey))))
                    {
                        AggreateSubList(subList.DetailList.Cast<AggregateModel>().ToList());
                        continue;
                    }
                    List<AggregateModel> list = AggregateSublist(subList.NextType, subList.DetailList);
                    int sum = list.Sum(t => t.Count);
                    list.ForEach(t => t.Percentage = (float)t.Count / (float)sum * 100);
 
                    AggreateSubList(list);
                    subList.DetailList = new ArrayList(list);
                }               
            }
            return target;
        }
        List<AggregateModel> AggregateSublist(ReportType key, ArrayList detailList)
        {
            ReportType nextCommand = (command.Last().Equals(key)) ? ReportType.None : command.ToList()[command.ToList().IndexOf(key) + 1];
            List<AggregateModel> rtnList = new List<AggregateModel>();
            switch (key)
            {
                case ReportType.Gender:
                    detailList.ToArray().GroupBy(w => ((MemberAnalysisDetailModel)w).Gender).Select(u => new MemberAnalysisDetailModel { Gender = u.Key, Count = u.ToList().Sum(item => ((MemberAnalysisDetailModel)item).Count) })
                        .ToList().ForEach(v => rtnList.Add(new AggregateModel() { GroupKey = v.Gender, Count = v.Count, DetailList = new ArrayList(detailList), NextType = nextCommand }));
                    break;
                case ReportType.Age:
                    detailList.ToArray().GroupBy(w => ((MemberAnalysisDetailModel)w).Age).Select(u => new MemberAnalysisDetailModel { Age = u.Key, Count = u.Sum(item => ((MemberAnalysisDetailModel)item).Count) })
                        .ToList().ForEach(v => rtnList.Add(new AggregateModel() { GroupKey = v.Age, Count = v.Count, DetailList = new ArrayList(detailList), NextType = nextCommand }));
                    break;
                case ReportType.Location:
                    rtnList = GenerateAreaReportData(detailList, nextCommand);
                    break;
                default:
                    break;
            }
            return rtnList;
        }
        void busyr_Cancel(object sender, EventArgs e)
        {           
            QueryView.busyr.IsBusy = false;
        }
 
        void RadioButtonClick(object sender, System.Windows.RoutedEventArgs e)
        {           
            DispatcherTimer timer = new DispatcherTimer();
            timer.Interval = TimeSpan.FromMilliseconds(100);
            timer.Tick += (s, e2) =>
            {
                string itemName = ((RadioButton)e.Source).Name;               
                var scheduler = TaskScheduler.FromCurrentSynchronizationContext();
                Task.Factory.StartNew(new Action<object>(ShowUI), (ReportType)Enum.Parse(typeof(ReportType), (string)itemName, true), CancellationToken.None, TaskCreationOptions.None, scheduler); 
                timer.Stop();
            };
            timer.Start();
            QueryView.busyr.IsBusy = true;
        }
        private void ShowUI(object itemName)
        {
            if (itemName == null)
                return;
            switch ((ReportType)itemName)
            {
                case ReportType.Gender:
                    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                        new Action(() => ShowGenderReport()));
                    break;
                case ReportType.Age:
                    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                        new Action(() => ShowAgeReport()));
                    break;
                case ReportType.Location:
                    Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
                        new Action(() => ShowLocationReport()));
                    break;
                case ReportType.None:
                    QueryView.Report.Children.Clear();
                    QueryView.PieChart.Children.Clear();
                    break;
                default:
                    break;
            }
            return;
        }
        void GeneratePieChart(IDictionary dictionary)
        {
            QueryView.PieChart.Children.Clear();
            RadChart chart = new RadChart() { Width = 500, Height = 300, FontSize = 12 };
 
            DataSeries series = new DataSeries();
             
            series.Definition = new PieSeriesDefinition();
            foreach (string s in dictionary.Keys)
            {
                series.Add(new Telerik.Windows.Controls.Charting.DataPoint() { LegendLabel = s, YValue = Convert.ToDouble(dictionary[s]) });
            }
            chart.DefaultView.ChartArea.DataSeries.Add(series);
            QueryView.PieChart.HorizontalAlignment = HorizontalAlignment.Right;
            QueryView.PieChart.Children.Add(chart);
        }
 
        private List<MemberAnalysisDetailModel> GetData()
        {
            if (token == null)
                token = AuthToken.GetInstance();
 
            if (string.IsNullOrEmpty(token.ThirdPartyID))
                return null;//       TODO;補登出
             
            ICacheManager cacheManager = CacheFactory.GetCacheManager();
            var data = cacheManager.GetData("RowData") as ReturnMessageOfArrayOfGetThirdPartyMemberAnalyOutputIfqRiZFe;
            if (data == null)
            {
                using (BusinessWCFReference.BusinessClient client = new BusinessClient())
                {
                    GetThirdPartyMemberAnalyInput input = new GetThirdPartyMemberAnalyInput() { Condition = 7, ThirdPartyID = token.ThirdPartyID };
                    data = client.GetThirdPartyMemberAnaly(input);
                }
                cacheManager.Add("RowData", data);
            }
            List<MemberAnalysisDetailModel> reportList = cacheManager.GetData("Report") as List<MemberAnalysisDetailModel>;
            if (reportList == null)
            {
                reportList = new List<MemberAnalysisDetailModel>();
                int count = 0;
                data.ReturnData.Where(t => (!string.IsNullOrEmpty(t.Age)) && (!string.IsNullOrEmpty(t.Gender)) && (!string.IsNullOrEmpty(t.Counts))).ToList()
                    .ForEach(t => reportList.Add(
                        new MemberAnalysisDetailModel() { Location = t.City, Age = t.Age, Gender = t.Gender, Count = int.TryParse(t.Counts, out count) ? count : 0 }));
 
                cacheManager.Add("Report", reportList);
            }
            return reportList;
        }
        private List<AggregateModel> GenerateAreaReportData(List<AggregateModel> list, ReportType nextCommand)
        {
            List<AggregateModel> areaList = new List<AggregateModel>();
            var statList = list.Where(u => Enum.GetNames(typeof(NorthArea)).Any(t => t.Equals(u.GroupKey))).ToList();
            if (statList.Count > 0)
            {
                areaList.Add(new AggregateModel { GroupKey = "北台灣", Count = statList.Sum(t => t.Count), DetailList = new ArrayList(statList), NextType = ReportType.Location });
                int res = statList.Sum(t => t.Count);
                statList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                list = list.Except((List<AggregateModel>)statList).ToList();
            }
            statList = list.Where(u => Enum.GetNames(typeof(CenterArea)).Any(t => t.Equals(u.GroupKey))).ToList();
            if (statList.Count > 0)
            {
                areaList.Add(new AggregateModel { GroupKey = "中台灣", Count = statList.Sum(t => t.Count), DetailList = new ArrayList(statList), NextType = ReportType.Location });
                int res = statList.Sum(t => t.Count);
                statList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                list = list.Except((List<AggregateModel>)statList).ToList();
            }
            statList = list.Where(u => Enum.GetNames(typeof(SouthArea)).Any(t => t.Equals(u.GroupKey))).ToList();
            if (statList.Count > 0)
            {
                areaList.Add(new AggregateModel { GroupKey = "南台灣", Count = statList.Sum(t => t.Count), DetailList = new ArrayList(statList), NextType = ReportType.Location });
                int res = statList.Sum(t => t.Count);
                statList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                list = list.Except((List<AggregateModel>)statList).ToList();
            }
            statList = list.Where(u => Enum.GetNames(typeof(EastArea)).Any(t => t.Equals(u.GroupKey))).ToList();
            if (statList.Count > 0)
            {
                areaList.Add(new AggregateModel { GroupKey = "東台灣", Count = statList.Sum(t => t.Count), DetailList = new ArrayList(statList), NextType = ReportType.Location });
                int res = statList.Sum(t => t.Count);
                statList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                list = list.Except((List<AggregateModel>)statList).ToList();
            }
            statList = list.Where(u => Enum.GetNames(typeof(OffshoreIsland)).Any(t => t.Equals(u.GroupKey))).ToList();
            if (statList.Count > 0)
            {
                areaList.Add(new AggregateModel { GroupKey = "外島或離島", Count = statList.Sum(t => t.Count), DetailList = new ArrayList(statList), NextType = ReportType.Location });
                int res = statList.Sum(t => t.Count);
                statList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                list = list.Except((List<AggregateModel>)statList).ToList();
            }
            if (list.Count > 0)
            {
                int res = list.Sum(t => t.Count);
                list.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel { GroupKey = "其他", Count = list.Sum(t => t.Count), DetailList = new ArrayList(list), NextType = ReportType.Location });
            }
            areaList.ForEach(t => t.Percentage = (float)t.Count / (float)areaList.Sum(u => u.Count) * 100);
            return areaList;
        }
        private List<AggregateModel> GenerateAreaReportData(ArrayList list, ReportType nextCommand)
        {
 
            List<AggregateModel> areaList = new List<AggregateModel>();
 
            var statList = list.Cast<MemberAnalysisDetailModel>().ToList().Where(u => Enum.GetNames(typeof(NorthArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var newList = statList.GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                int res = newList.Sum(t => t.Count);
                newList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel { GroupKey = "北台灣", Count = newList.Sum(t => t.Count), DetailList = new ArrayList(newList), NextType = ReportType.Location });
                list = new ArrayList(list.Cast<MemberAnalysisDetailModel>().ToList().Except((List<MemberAnalysisDetailModel>)statList).ToList());
            }
 
            statList = list.Cast<MemberAnalysisDetailModel>().ToList().Where(u => Enum.GetNames(typeof(CenterArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var newList = statList.GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                int res = newList.Sum(t => t.Count);
                newList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel { GroupKey = "中台灣", Count = newList.Sum(t => t.Count), DetailList = new ArrayList(newList), NextType = ReportType.Location });
                list = new ArrayList(list.Cast<MemberAnalysisDetailModel>().ToList().Except((List<MemberAnalysisDetailModel>)statList).ToList());
            }
 
            statList = list.Cast<MemberAnalysisDetailModel>().ToList().Where(u => Enum.GetNames(typeof(SouthArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var newList = statList.GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                int res = newList.Sum(t => t.Count);
                newList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel { GroupKey = "南台灣", Count = newList.Sum(t => t.Count), DetailList = new ArrayList(newList), NextType = ReportType.Location });
                list = new ArrayList(list.Cast<MemberAnalysisDetailModel>().ToList().Except((List<MemberAnalysisDetailModel>)statList).ToList());
            }
            statList = list.Cast<MemberAnalysisDetailModel>().ToList().Where(u => Enum.GetNames(typeof(EastArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var newList = statList.GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                int res = newList.Sum(t => t.Count);
                newList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel { GroupKey = "東台灣", Count = newList.Sum(t => t.Count), DetailList = new ArrayList(newList), NextType = ReportType.Location });
                list = new ArrayList(list.Cast<MemberAnalysisDetailModel>().ToList().Except((List<MemberAnalysisDetailModel>)statList).ToList());
            }
            statList = list.Cast<MemberAnalysisDetailModel>().ToList().Where(u => Enum.GetNames(typeof(OffshoreIsland)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var newList = statList.GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                int res = newList.Sum(t => t.Count);
                newList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel { GroupKey = "外島或離島", Count = newList.Sum(t => t.Count), DetailList = new ArrayList(newList), NextType = ReportType.Location });
                list = new ArrayList(list.Cast<MemberAnalysisDetailModel>().ToList().Except((List<MemberAnalysisDetailModel>)statList).ToList());
            }
            if (list.Count > 0)
            {
                var newList = list.Cast<MemberAnalysisDetailModel>().ToList().GroupBy(w => w.Location).Select(u => new AggregateModel { GroupKey = u.Key, Count = u.Sum(item => item.Count), DetailList = new ArrayList(u.ToList()), NextType = nextCommand }).ToList();
                int res = newList.Sum(t => t.Count);
                newList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AggregateModel() { GroupKey = "其他", Count = list.Cast<MemberAnalysisDetailModel>().ToList().Sum(t => t.Count), DetailList = new ArrayList(newList), NextType = ReportType.Location });
            }
            return areaList;
        }
        private List<AreaModel> GenerateAreaReportData()
        {
            var data = cacheManager.GetData("AreaReport") as List<AreaModel>;
            if (data != null)
                return data;
            List<AreaModel> areaList = new List<AreaModel>();
            List<MemberAnalysisDetailModel> list = GetData();
             
            var statList = list.Where(u => Enum.GetNames(typeof(NorthArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var countryList = statList.GroupBy(w => w.Location).Select(u => new MemberAnalysisDetailModel { Location = u.Key, Count = u.Sum(item => item.Count) }).ToList();
                int res = countryList.Sum(t => t.Count);
                countryList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AreaModel() { Area = " 北台灣", Count = countryList.Sum(t => t.Count), CountriesList = countryList });
                list = list.Except((List<MemberAnalysisDetailModel>)statList).ToList();
            }
            statList = list.Where(u => Enum.GetNames(typeof(CenterArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var countryList = statList.GroupBy(w => w.Location).Select(u => new MemberAnalysisDetailModel { Location = u.Key, Count = u.Sum(item => item.Count) }).ToList();
                int res = countryList.Sum(t => t.Count);
                countryList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AreaModel() { Area = "中台灣", Count = countryList.Sum(t => t.Count), CountriesList = countryList });
                list = list.Except((List<MemberAnalysisDetailModel>)statList).ToList();
            }
 
            statList = list.Where(u => Enum.GetNames(typeof(SouthArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var countryList = statList.GroupBy(w => w.Location).Select(u => new MemberAnalysisDetailModel { Location = u.Key, Count = u.Sum(item => item.Count) }).ToList();
                int res = countryList.Sum(t => t.Count);
                countryList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AreaModel() { Area = "南台灣", Count = countryList.Sum(t => t.Count), CountriesList = countryList });
                list = list.Except((List<MemberAnalysisDetailModel>)statList).ToList();
            }
 
            statList = list.Where(u => Enum.GetNames(typeof(EastArea)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var countryList = statList.GroupBy(w => w.Location).Select(u => new MemberAnalysisDetailModel { Location = u.Key, Count = u.Sum(item => item.Count) }).ToList();
                int res = countryList.Sum(t => t.Count);
                countryList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AreaModel() { Area = "東台灣", Count = countryList.Sum(t => t.Count), CountriesList = countryList });
                list = list.Except((List<MemberAnalysisDetailModel>)statList).ToList();
            }
 
            statList = list.Where(u => Enum.GetNames(typeof(OffshoreIsland)).Any(t => t.Equals(u.Location))).ToList();
            if (statList.Count > 0)
            {
                var countryList = statList.GroupBy(w => w.Location).Select(u => new MemberAnalysisDetailModel { Location = u.Key, Count = u.Sum(item => item.Count) }).ToList();
                int res = countryList.Sum(t => t.Count);
                countryList.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AreaModel() { Area = "外島或離島", Count = countryList.Sum(t => t.Count), CountriesList = countryList });
                list = list.Except((List<MemberAnalysisDetailModel>)statList).ToList();
            }
            if (list.Count > 0)
            {
                int res = list.Sum(t => t.Count);
                list.ForEach(t => t.Percentage = (float)t.Count / (float)res * 100);
                areaList.Add(new AreaModel() { Area = "其他", Count = list.Sum(t => t.Count), CountriesList = list });
                areaList.ForEach(t => t.Percentage = (float)t.Count / (float)areaList.Sum(u => u.Count) * 100);
            }
            int sum = areaList.Sum(t => t.Count);
            areaList.ForEach(t => t.Percentage = (float)t.Count / (float)sum * 100);
            cacheManager.Add("AreaReport", areaList);
            return areaList;
        }
        private void ShowLocationReport()
        {
            QueryView.Report.Children.Clear();
            QueryView.Report.Children.Add(GenerateAreaView());
            QueryView.busyr.IsBusy = false;
        }
        private RadGridView GenerateAreaView()
        {
            List<AreaModel> areaList = GenerateAreaReportData();
            string key = "Area";
            RadGridView aggregateView = GenerateGridview(key);
            if (aggregateView == null)
                throw new Exception("Fail!!");
            aggregateView.ItemTemplate = CreateDataTemplate();
            aggregateView.ItemsSource = areaList;
            Dictionary<string, int> dictionary = areaList
                .GroupBy(p => p.Area, StringComparer.OrdinalIgnoreCase)
                .ToDictionary(g => g.Key, g => g.First().Count, StringComparer.OrdinalIgnoreCase);
            GeneratePieChart(dictionary);
            return aggregateView;
        }
        private void ShowAgeReport()
        {
            string key = "Age";
            RadGridView view = GenerateGridview(key);
            if (view == null)
                throw new Exception("Fail!!");
            QueryView.Report.Children.Clear();
            QueryView.Report.Children.Add(view);
             
            List<MemberAnalysisDetailModel> statList = GetData();
            var res = statList.GroupBy(w => w.Age).Select(u => new MemberAnalysisDetailModel { Age = u.Key, Count = u.Sum(item => item.Count) }).ToList();
            int sum = res.Sum(t => t.Count);
            res.ForEach(t => t.Percentage = (float)t.Count / (float)sum * 100);
            view.ItemsSource = res.OrderBy(t=>t.Age).ToList();
            Dictionary<string, int> dictionary = res.GroupBy(p => p.Age, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g.First().Count, StringComparer.OrdinalIgnoreCase);
            GeneratePieChart(dictionary);
            QueryView.busyr.IsBusy = false;
        }
        private void ShowGenderReport()
        {
            string key = "Gender";
            RadGridView view = GenerateGridview(key);
            if (view == null)
                throw new Exception("Fail!!");
            QueryView.Report.Children.Clear();
            QueryView.Report.Children.Add(view);
            List<MemberAnalysisDetailModel> statList = GetData();
            var res = statList.GroupBy(w => w.Gender).Select(u => new MemberAnalysisDetailModel { Gender = u.Key, Count = u.Sum(item => item.Count) }).ToList();
            int sum = res.Sum(t => t.Count);
            res.ForEach(t => t.Percentage = (float)t.Count / (float)sum * 100);
            view.ItemsSource = res;
            Dictionary<string,int> dictionary = res.GroupBy(p => p.Gender, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g.First().Count, StringComparer.OrdinalIgnoreCase);
            GeneratePieChart(dictionary);
            QueryView.busyr.IsBusy = false;
        }
        private RadGridView GenerateGridview(string key)
        {
            GridViewDataColumn column = (GridViewDataColumn)HeaderDictionary[key];
            if (column == null)
                return null;
 
            RadGridView view = new RadGridView()
            {
                CanUserSortGroups = false,
                CanUserInsertRows = false,
                CanUserFreezeColumns = false,
                CanUserDeleteRows = false,
                AutoGenerateColumns = false,
                ShowGroupPanel = false,
                ShowColumnFooters = true,
                ShowGroupFooters = true,
                MaxHeight = QueryView.Report.MaxHeight
            };
            if ("area".Equals(key, StringComparison.CurrentCultureIgnoreCase))
            {
                view.RowDetailsTemplate = CreateDataTemplate();
                GridViewToggleRowDetailsColumn toggleRowColumn = new GridViewToggleRowDetailsColumn();               
                view.Columns.Add(toggleRowColumn);
            }
            view.Columns.Add(column);
            view.RowDetailsVisibilityChanged += new EventHandler<Telerik.Windows.Controls.GridView.GridViewRowDetailsEventArgs>(view_RowDetailsVisibilityChanged);
            view.Columns.Add((GridViewDataColumn)HeaderDictionary["Count"]);
            view.Columns.Add((GridViewDataColumn)HeaderDictionary["Percentage"]);
            return view;
        }
 
        void view_RowDetailsVisibilityChanged(object sender, Telerik.Windows.Controls.GridView.GridViewRowDetailsEventArgs e)
        {
            Dictionary<string, int> dictionary = (e.Visibility.Equals(Visibility.Visible))?
                ((AreaModel)e.Row.Item).CountriesList.GroupBy(p => p.Location, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g.First().Count, StringComparer.OrdinalIgnoreCase):
                GenerateAreaReportData().GroupBy(p => p.Area, StringComparer.OrdinalIgnoreCase).ToDictionary(g => g.Key, g => g.First().Count, StringComparer.OrdinalIgnoreCase);
            GeneratePieChart(dictionary);
        }
        private void GenerateHeaderDictionary()
        {
            HeaderDictionary.Add("Age", new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("Age"), Header = "年齡", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, Width = 80, TextAlignment = System.Windows.TextAlignment.Center });
            HeaderDictionary.Add("Gender", new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("Gender"), Header = "性別", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, Width = 80, TextAlignment = System.Windows.TextAlignment.Center });
            HeaderDictionary.Add("Area", new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("Area"), Header = "區域", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, Width = 80, TextAlignment = System.Windows.TextAlignment.Center });
            HeaderDictionary.Add("AgeMultiSelected", new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("GroupKey"), Header = "年齡", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, Width = 80, TextAlignment = System.Windows.TextAlignment.Center });
            HeaderDictionary.Add("LocationMultiSelected", new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("GroupKey"), Header = "區域", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, Width = 80, TextAlignment = System.Windows.TextAlignment.Center });
            HeaderDictionary.Add("GenderMultiSelected", new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("GroupKey"), Header = "性別", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, Width = 80, TextAlignment = System.Windows.TextAlignment.Center });
            GridViewDataColumn column = new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("Count"), Header = "人數", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, DataFormatString = "{0:N0}", TextAlignment = System.Windows.TextAlignment.Right, Width = 80 };
            column.AggregateFunctions.Add(new SumFunction() { Caption = "總計", FunctionName = "Count", ResultFormatString = "{0:N0}" });
            HeaderDictionary.Add("Count", column);
            column = new GridViewDataColumn() { DataMemberBinding = new System.Windows.Data.Binding("Percentage"), Header = "百分比", IsReadOnly = true, TabStopMode = Telerik.Windows.Controls.GridView.GridViewTabStop.Skip, DataFormatString = "{0:f2}%", TextAlignment = System.Windows.TextAlignment.Right, Width = 80 };
            column.AggregateFunctions.Add(new SumFunction() { SourceField = "Percentage", ResultFormatString = "{0:f2}%" });
            HeaderDictionary.Add("Percentage", column);
 
            HeaderKeyDictionary.Add("Age", "年齡");
            HeaderKeyDictionary.Add("Gender", "性別");
            HeaderKeyDictionary.Add("Location", "區域");
        }
        private DataTemplate CreateNewDataTemplate()
        {
            string rtnXaml = string.Empty;
            string baseXaml = @"<DataTemplate x:Key='RowDetailsTemplate'
                    xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                    xmlns:telerik='http://schemas.telerik.com/2008/xaml/presentation'
                    xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
                    <telerik:RadGridView Name='SubListGrid{KEYTYPE}' ItemsSource='{Binding DetailList}' AutoGenerateColumns='False' CanUserSortGroups='False' CanUserInsertRows='False' CanUserFreezeColumns='False' CanUserDeleteRows='False' ShowGroupPanel='False' IsReadOnly='true'>
                        <telerik:RadGridView.Columns>
                            {TOGGLEROWDETAILCOLUMN}
                            <telerik:GridViewDataColumn Header='{HEADER}' DataMemberBinding='{Binding GroupKey}' TextAlignment='Center'/>
                            <telerik:GridViewDataColumn Header='人數' DataMemberBinding='{Binding Count}' TextAlignment='Right' DataFormatString = '{}{0:N0}'/>
                            <telerik:GridViewDataColumn Header='百分比' DataMemberBinding='{Binding Percentage}' DataFormatString = '{}{0:f2}%' TextAlignment='Right'/>
                        </telerik:RadGridView.Columns>
                  {SUBTEMPLATE}
                  </telerik:RadGridView>
                </DataTemplate>";
            string subLevelXaml = @"<telerik:RadGridView.RowDetailsTemplate>
                    <DataTemplate x:Key='RowDetailsTemplate'>
                    <telerik:RadGridView Name='SubListGrid{KEYTYPE}' ItemsSource='{Binding DetailList}' AutoGenerateColumns='False' CanUserSortGroups='False' CanUserInsertRows='False' CanUserFreezeColumns='False' CanUserDeleteRows='False' ShowGroupPanel='False' IsReadOnly='true'>
                        <telerik:RadGridView.Columns>
                            {TOGGLEROWDETAILCOLUMN}
                            <telerik:GridViewDataColumn Header='{HEADER}' DataMemberBinding='{Binding GroupKey}' TextAlignment='Center'/>
                            <telerik:GridViewDataColumn Header='人數' DataMemberBinding='{Binding Count}' TextAlignment='Right' DataFormatString = '{}{0:N0}'/>
                            <telerik:GridViewDataColumn Header='百分比' DataMemberBinding='{Binding Percentage}' DataFormatString = '{}{0:f2}%' TextAlignment='Right'/>
                        </telerik:RadGridView.Columns>
                  {SUBTEMPLATE}
                  </telerik:RadGridView>
                </DataTemplate>
                </telerik:RadGridView.RowDetailsTemplate>";
            foreach (ReportType type in command)
            {
                if (command.First().Equals(type))
                {
                    if (ReportType.Location.Equals(type))
                        rtnXaml = baseXaml.Replace("{KEYTYPE}", "Area").Replace("{HEADER}", "縣/市");
                    continue;
                }
                if (rtnXaml.Equals(string.Empty))
                {
                    rtnXaml = baseXaml.Replace("{KEYTYPE}", type.ToString()).Replace("{HEADER}", HeaderKeyDictionary[type.ToString()].ToString());
                }
                else
                {
                    string subXaml = subLevelXaml.Replace("{KEYTYPE}", type.ToString()).Replace("{HEADER}", HeaderKeyDictionary[type.ToString()].ToString());
                    rtnXaml = rtnXaml.Replace("{TOGGLEROWDETAILCOLUMN}", "<telerik:GridViewToggleRowDetailsColumn/>").Replace("{SUBTEMPLATE}", subXaml);
                }
                if (ReportType.Location.Equals(type))
                {
                    string subXaml = subLevelXaml.Replace("{KEYTYPE}", "Area").Replace("{HEADER}", "縣/市");
                    rtnXaml = rtnXaml.Replace("{TOGGLEROWDETAILCOLUMN}", "<telerik:GridViewToggleRowDetailsColumn/>").Replace("{SUBTEMPLATE}", subXaml);
                }
            }
            rtnXaml = rtnXaml.Replace("{TOGGLEROWDETAILCOLUMN}", string.Empty).Replace("{SUBTEMPLATE}", string.Empty);
            System.Text.UTF8Encoding myEncoder = new System.Text.UTF8Encoding();
            byte[] bytes = myEncoder.GetBytes(rtnXaml);
            MemoryStream ms = new MemoryStream(bytes);
            DataTemplate dt = (DataTemplate)XamlReader.Load(ms);           
            return dt;
        }
        private DataTemplate CreateDataTemplate()
        {
            string xaml =
                @"<DataTemplate x:Key='RowDetailsTemplate'
                    xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
                    xmlns:telerik='http://schemas.telerik.com/2008/xaml/presentation'
                    xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
                    <telerik:RadGridView Name='CountryGrid' ItemsSource='{Binding CountriesList}' AutoGenerateColumns='False' CanUserSortGroups='False' CanUserInsertRows='False' CanUserFreezeColumns='False' CanUserDeleteRows='False' ShowGroupPanel='False' IsReadOnly='true'>
                        <telerik:RadGridView.Columns>
                            <telerik:GridViewDataColumn Header='縣/市' DataMemberBinding='{Binding Location}' TextAlignment='Center'/>
                            <telerik:GridViewDataColumn Header='人數' DataMemberBinding='{Binding Count}' TextAlignment='Right' DataFormatString = '{}{0:N0}'/>
                            <telerik:GridViewDataColumn Header='百分比' DataMemberBinding='{Binding Percentage}' DataFormatString = '{}{0:f2}%' TextAlignment='Right'/>
                        </telerik:RadGridView.Columns>
                    </telerik:RadGridView>
                </DataTemplate>";
            System.Text.UTF8Encoding myEncoder = new System.Text.UTF8Encoding();
            byte[] bytes = myEncoder.GetBytes(xaml);
            MemoryStream ms = new MemoryStream(bytes);
            DataTemplate dt = (DataTemplate)XamlReader.Load(ms);
            return dt;
        }      
        public override bool ExitCommandBinding_CanExecuted(object parameter)
        {
            return base.ExitCommandBinding_CanExecuted(parameter);
        }
        public override void ExitCommandBinding_Executed(object parameter)
        {
            base.ExitCommandBinding_Executed(parameter);
        }
    }
}

No answers yet. Maybe you can help?

Tags
GridView
Asked by
Russel
Top achievements
Rank 1
Share this question
or