protected override void _bgWorker_DoWork(object sender, System.ComponentModel.DoWorkEventArgs e)
        {
            IsBusy = true;
            //_selectedProps = new Dictionary<int, string>();
            //_selectedProps.Add(12,"AA");
            //_selectedComps = new Dictionary<int, string>();
            //_selectedComps.Add(28, "AAA");
            if (_selectedComps == null || _selectedComps.Count == 0)
            {
                return;
            }

            App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
            {
                _propRptItems.Clear();
                PropContent.Clear();
            });

            lock (_selectedComps)
            {
                //決定最後要分析的項目
                StringBuilder sqlString = new StringBuilder();
                sqlString.AppendFormat("PROP_INDEX in ({0}) and TEST_ITEM_INDEX in ({1})",
                                       string.Join(",", _selectedProps.Select(x => "'" + x.Key + "'")),
                                       string.Join(",", _selectedComps.Select(x => "'" + x.Key + "'")));
                DataRow[] prop_comp_list;
                prop_comp_list = _ds.Tables["PROP_COMP_INFO"].Select(sqlString.ToString(), "PROD_NAME");
                string[] itemList = prop_comp_list.Select(x => x.Field <int>("PROP_INDEX") + "/" + x.Field <int>("TEST_ITEM_INDEX")).Distinct().ToArray();

                string               start = string.Format("{0:yyyy-MM-dd} {1}", StartDate.Date, StartTimeValue);
                string               end   = string.Format("{0:yyyy-MM-dd} {1}", EndDate.Date, EndTimeValue);
                DataTable            rawData;
                Model.PropertyReport rpt;

                //itemList = new string[]{"12/28","12/29","12/31","14/28","14/31","14/32"};
                //start = string.Format("2016-10-01 {1}", StartDate.Date, StartTimeValue);

                rawData = Database.DBQueryTool.GetPropertyTestData(itemList, start, end);
                if (rawData == null || rawData.Rows.Count == 0)
                {
                    throw new ArgumentNullException("查無資料");
                }

                //把資料依分析項和成分分群
                List <DataTable> subData = rawData.AsEnumerable().GroupBy(x => new { PROP_ID = x.Field <int>("PROP_INDEX"), ITEM_ID = x.Field <int>("TEST_ITEM_INDEX") })
                                           .Select(g => g.CopyToDataTable()).ToList();

                string tmpDir = System.IO.Path.Combine(Environment.GetEnvironmentVariable("tmp"), "Minitab");
                Array.ForEach(System.IO.Directory.GetFiles(tmpDir), System.IO.File.Delete); //刪除暫存區所有檔案


                for (int i = 0; i < subData.Count; i++)
                {
                    rpt         = new Model.PropertyReport();
                    rpt.RawData = subData[i];
                    rpt.Title   = subData[i].Rows[0]["PROD_NAME"].ToString() + ": " + subData[i].Rows[0]["ITEM_NAME"].ToString();
                    try
                    {
                        rpt.Execute(Project);
                    }
                    catch (ArgumentNullException argnullex)
                    {
                        throw new ArgumentNullException(argnullex.Message);
                    }
                    catch (Exception ex)
                    {
                        throw new Exception("Minitab run time error\r\n" + ex.Message);
                    }
                    App.Current.Dispatcher.Invoke((Action) delegate // <--- HERE
                    {
                        _propRptItems.Add(rpt);
                    });
                }
            }
        }
        /// <summary>
        /// 報表內容異動,觸發顯示於頁面的內容也要更動
        /// </summary>
        /// <param name="sender"></param>
        /// <param name="e"></param>
        private void _propRptItems_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e)
        {
            List <Model.IReport> newItems;

            if (e.NewItems != null)
            {
                newItems = e.NewItems.Cast <Model.IReport>().ToList();
            }
            else
            {
                newItems = new List <Model.IReport>();
            }
            List <Model.IReport> oldItems;

            if (e.OldItems != null)
            {
                oldItems = e.OldItems.Cast <Model.IReport>().ToList();
            }
            else
            {
                oldItems = new List <Model.IReport>();
            }
            PropReportContent tmpContent;

            switch (e.Action)
            {
            case System.Collections.Specialized.NotifyCollectionChangedAction.Add:
                for (int i = 0; i < newItems.Count; i++)
                {
                    Model.IReport rpt = newItems[i];
                    tmpContent = new PropReportContent();
                    for (int j = 0; j < rpt.Contents.Count; j++)
                    {
                        Model.IRptOutput output = rpt.Contents[j];
                        switch (output.OType)
                        {
                        case Dashboard.Model.MtbOType.GRAPH:
                            tmpContent.Chart             = Tool.BinaryToWPFImage(output.OutputInByteArr);
                            tmpContent.VisibilityOfChart = true;
                            break;

                        case Dashboard.Model.MtbOType.TABLE:
                            tmpContent.Table     = Tool.BinaryToDataTable(output.OutputInByteArr);
                            tmpContent.ShowTable = true;
                            break;

                        default:
                            break;
                        }
                    }
                    tmpContent.Title   = rpt.Title;
                    tmpContent.RawData = rpt.RawData;
                    PropContent.Add(tmpContent);
                }
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Remove:
                PropContent.Clear();
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Replace:
                for (int i = 0; i < newItems.Count; i++)
                {
                    Model.IReport rpt = newItems[i];
                    tmpContent = new PropReportContent();
                    for (int j = 0; j < rpt.Contents.Count; j++)
                    {
                        Model.IRptOutput output = rpt.Contents[j];
                        switch (output.OType)
                        {
                        case Dashboard.Model.MtbOType.GRAPH:
                            tmpContent.Chart             = Tool.BinaryToWPFImage(output.OutputInByteArr);
                            tmpContent.VisibilityOfChart = true;
                            break;

                        case Dashboard.Model.MtbOType.TABLE:
                            tmpContent.Table     = Tool.BinaryToDataTable(output.OutputInByteArr);
                            tmpContent.ShowTable = true;
                            break;

                        default:
                            break;
                        }
                    }
                    tmpContent.Title   = rpt.Title;
                    tmpContent.RawData = rpt.RawData;
                    PropContent[e.OldStartingIndex + i] = tmpContent;
                }
                break;

            case System.Collections.Specialized.NotifyCollectionChangedAction.Move:
            case System.Collections.Specialized.NotifyCollectionChangedAction.Reset:
            default:
                break;
            }
        }