Set event inside nested datatemplate

1 posts, 0 answers
  1. Russel
    Russel avatar
    1 posts
    Member since:
    Nov 2012

    Posted 16 Dec 2012 Link to this post

    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);
            }
        }
    }
Back to Top