private void Load(object sender, MouseButtonEventArgs e)
        {
            if (MidiPath.Text != "" && new FileInfo(MidiPath.Text).Exists)
            {
                var m = MidiPath.Text;
                //Waiting...
                var w = new SubWindow.Waiting(); w.Owner = this;
                BackgroundWorker waiting = new BackgroundWorker();
                waiting.DoWork             += (ee, ea) => { };
                waiting.RunWorkerCompleted += (ee, ea) =>
                {
                    Dispatcher.BeginInvoke(new Action(() =>
                    {
                        try { w.ShowDialog(); } catch { }
                    }));
                };
                waiting.RunWorkerAsync();
                //Work
                BackgroundWorker worker = new BackgroundWorker();
                worker.WorkerReportsProgress = true;
                worker.DoWork += (o, ea) =>
                {
                    if (oldMidi == m)
                    {
                        preTimeLine = UpdateMidiInspector(new AudioStreamMidi().SerializeByRate(m, new TimeLine(), 1, SetProgressBar), preTimeLine);
                    }
                    else
                    {
                        preTimeLine = new AudioStreamMidi().SerializeByRate(m, new TimeLine(), 1, SetProgressBar);
                    }
                };
                worker.RunWorkerCompleted += (o, ea) =>
                {
                    w.Close();
                    Midipath = MidiPath.Text;
                    MidiSetting.IsEnabled = true;
                    MidiSetting.ReadListView(preTimeLine);
                    MidiSetting.TracksView.ItemsSource = MidiSetting.TrackMarkerList; //Track
                    MidiSetting.Plat.IsEnabled         = true;
                    MidiSetting.ItemChanged();

                    save.IsEnabled           = true;
                    export_setting.IsEnabled = true;
                    oldMidi = MidiPath.Text;
                    SetProgressBar(0);

                    exportSetting.SwitchBeat((int)preTimeLine.TicksPerBeat);
                    exportSetting.SwitchRate(1);
                    exportSetting.Ok.IsEnabled = false;
                    exportSetting.Info2.Text   = preTimeLine.Param["TotalTicks"].Value.ToString() + " ticks";
                    var _m = preTimeLine.Param["TotalTicks"].Value / 1200;
                    var s  = preTimeLine.Param["TotalTicks"].Value % 1200 / 20;
                    exportSetting.Info1.Text = _m.ToString() + " : " + s.ToString();
                };
                worker.RunWorkerAsync();
            }
        }
        private void LoadFile(object sender, MouseButtonEventArgs e)
        {
            OpenFileDialog fileDialog = new OpenFileDialog();

            fileDialog.Filter      = "ExecutiveMidi Project(*.emidiproj)|*.emidiproj";
            fileDialog.FilterIndex = 1;
            if (fileDialog.ShowDialog() == true && fileDialog.FileName != null && fileDialog.FileName != "")
            {
                var o = JsonConvert.DeserializeObject <Emidiproj>(_coding.Decompress(File.ReadAllText(fileDialog.FileName)));
                //relative or absolute or cancel
                var msg = MessageBox.Show("是否使用相对路径导入?", "使用相对路径导入", MessageBoxButton.YesNoCancel); if (msg == MessageBoxResult.Cancel)
                {
                    return;
                }
                if (msg == MessageBoxResult.Yes)
                {
                    o.Midipath = (o.rMidipath != null) ? new Uri(new Uri(fileDialog.FileName.Replace(" ", "*20")), o.rMidipath).LocalPath.Replace("*20", " ") : "";
                }
                if (o.Midipath != "" && new FileInfo(o.Midipath).Exists) //MidiPath
                {
                    Midipath              = o.Midipath;
                    MidiPath.Text         = o.Midipath;
                    MidiSetting.IsEnabled = true;
                    MidiSetting.ItemChanged();
                    cancel0.Visibility = Visibility.Visible;
                    Rate        = o.Rate;
                    SynchroTick = o.SynchroTick;
                    var m = o.Midipath;
                    //Waiting...
                    var w = new SubWindow.Waiting(); w.Owner = this;
                    BackgroundWorker waiting = new BackgroundWorker();
                    waiting.DoWork             += (ee, ea) => { };
                    waiting.RunWorkerCompleted += (ee, ea) =>
                    {
                        Dispatcher.BeginInvoke(new Action(() =>
                        {
                            try { w.ShowDialog(); } catch { }
                        }));
                    };
                    waiting.RunWorkerAsync();
                    //Work
                    BackgroundWorker worker = new BackgroundWorker();
                    worker.WorkerReportsProgress = true;
                    worker.DoWork += (ou, ea) =>
                    {
                        if (o.SynchroTick <= 0)
                        {
                            if (oldMidi == m)
                            {
                                preTimeLine = UpdateMidiInspector(new AudioStreamMidi().SerializeByRate(m, new TimeLine(), o.Rate, SetProgressBar), preTimeLine);
                            }
                            else
                            {
                                preTimeLine = new AudioStreamMidi().SerializeByRate(m, new TimeLine(), o.Rate, SetProgressBar);
                            }
                            SetProgressBar(0);
                        }
                        else
                        {
                            SetTotalProgressStage(2);
                            if (oldMidi == m)
                            {
                                preTimeLine = UpdateMidiInspector(new AudioStreamMidi().SerializeByBeat(m, new TimeLine(), o.SynchroTick, SetProgressBar), preTimeLine);
                            }
                            else
                            {
                                preTimeLine = new AudioStreamMidi().SerializeByBeat(m, new TimeLine(), o.SynchroTick, SetProgressBar);
                            }
                            AddProgressStage();
                            int last_bpm = -1;
                            for (int i = 0; i < preTimeLine.TickNodes.Count; i++)
                            {
                                if (preTimeLine.TickNodes[i].BPM >= 0 && preTimeLine.TickNodes[i].BPM != last_bpm) //BPM changed
                                {
                                    double tps = (double)preTimeLine.TickNodes[i].BPM * preTimeLine.TicksPerBeat / 60 / SynchroTick;
                                    exportSetting.beatElements.Add(new SubWindow.BeatElement()
                                    {
                                        BPM       = preTimeLine.TickNodes[i].BPM.ToString(),
                                        TickStart = i,
                                        TPS       = tps.ToString("0.0000")
                                    });
                                    last_bpm = preTimeLine.TickNodes[i].BPM;
                                }
                                SetStagedProgressBar((double)i / preTimeLine.TickNodes.Count);
                            }
                            ResetProgressStage();
                        }
                    };
                    worker.RunWorkerCompleted += (ou, ea) =>
                    {
                        MidiSetting.ReadListView(preTimeLine);
                        MidiSetting.UpdateListView(o.TrackMarkerList, o.InstrumentMarkerList);
                        w.Close();
                        MidiSetting.IsEnabled              = true;
                        MidiSetting.Plat.IsEnabled         = true;
                        MidiSetting.TracksView.ItemsSource = MidiSetting.TrackMarkerList;
                        MidiSetting.ItemChanged();
                        save.IsEnabled           = true;
                        export_setting.IsEnabled = true;
                        if (SynchroTick > 0)
                        {
                            exportSetting.SwitchBeat(SynchroTick);
                            exportSetting.Info1.Text = (preTimeLine.SynchronousRate * 100).ToString("0.00") + "%";
                            var toolTip = new TextBlock();
                            toolTip.Text = "有 " + (int)((1 - preTimeLine.SynchronousRate) * preTimeLine.Param["TotalTicks"].Value) + " 个音符与原Midi不同步.\n序列总长度为 " + preTimeLine.TickNodes.Count + " .";
                            exportSetting.Info1.ToolTip = toolTip;
                        }
                        else
                        {
                            exportSetting.SwitchRate(Rate);
                            exportSetting.Info2.Text = preTimeLine.Param["TotalTicks"].Value.ToString() + " ticks";
                            var _m = preTimeLine.Param["TotalTicks"].Value / 1200;
                            var s  = preTimeLine.Param["TotalTicks"].Value % 1200 / 20;
                            exportSetting.Info1.Text = _m.ToString() + " : " + s.ToString();
                            SynchroTick = -1;
                        }
                        exportSetting.Ok.IsEnabled = false;
                        oldMidi = MidiPath.Text;
                    };
                    worker.RunWorkerAsync();
                }
                else
                {
                    MidiSetting.IsEnabled = false;
                    cancel0.Visibility    = Visibility.Hidden;
                }
            }
        }