2016-06-21 15 views
3

Visual Studio 2015でMVVM Light WPFアプリケーションを構築していますが、これにはWindowsFormsHostと、SQL Server Reporting ServicesローカルレポートのReportViewerを含むユーザーコントロールがあります。 ReportView.xamlのボタンはコマンドを呼び出し、次にコマンドをMasterListView.xamlのコードビハインドに送信してレポートを生成します。ここでビジー状態インジケーターが表示されない

public ICommand RunReportRelayCommand => 
    new RelayCommand(async()=> { await RunReport(); }); 

private async Task RunReport() 
{ 
    try 
    { 
     IsBusy = true; 
     await Task.Run(() => 
     { 
      Messenger.Default.Send(true, "RunMasterListReport"); 
     }); 
    } 
    finally 
    { 
     IsBusy = false; 
    } 
} 

ReportViewModel.csIsBusyプロパティの定義です:ここで

ReportViewModel.csのボタンによって呼び出されるコマンドです

private bool _isBusy; 
public bool IsBusy 
{ 
    get { return _isBusy; } 
    set 
    { 
     if (value == _isBusy) return; 
     _isBusy = value; 
     RaisePropertyChanged(); 
    } 
} 

上記を呼び出すボタンが含まれている同じビュー、ReportView.xaml、コマンドには、次の拡張WPFツールキットビジーインジケータが含まれます。

<UserControl> 
    <UserControl.Resources> 
     <DataTemplate x:Key="MasterListViewTemplate"> 
      <view:MasterListView /> 
     </DataTemplate> 
    </UserControl.Resources> 
    <xctk:BusyIndicator IsBusy="{Binding IsBusy}"> 
     <StackPanel> 
      <!-- Other XAML here --> 
      <ContentControl ContentTemplate="{StaticResource MasterListViewTemplate}" /> 
     </StackPanel> 
    </xctk:BusyIndicator> 
</UserControl> 

次にMasterListView.csにコードビハインド、我々はこれを持っている:レポートが5秒ほど後に表示さんが

public partial class MasterListView : UserControl 
{ 
    public MasterListView() 
    { 
     InitializeComponent(); 
     Messenger.Default.Register<bool>(this, "RunMasterListReport", RunMasterListReport); 
    } 

    public async void RunMasterListReport(bool val) 
    {   
     await Task.Run(() => 
     { 
      var dataSet = new DrugComplianceDataSet(); 
      dataSet.BeginInit(); 
      ReportViewer.ProcessingMode = ProcessingMode.Local; 
      ReportViewer.LocalReport.ShowDetailedSubreportMessages = true; 
      ReportViewer.LocalReport.DataSources.Clear(); 
      var dataSource = new ReportDataSource 
      { 
       Name = "MasterListRandomDataSet", 
       Value = dataSet.MasterListRandom 
      }; 
      ReportViewer.LocalReport.DataSources.Add(dataSource); 
      ReportViewer.LocalReport.ReportEmbeddedResource = "MasterListRandom.rdlc"; 
      dataSet.EndInit(); 
      var adapter = new MasterListRandomTableAdapter { ClearBeforeFill = true } 
       .Fill(dataSet.MasterListRandom); 
      Dispatcher.Invoke((MethodInvoker)(() => { ReportViewer.RefreshReport(); })); 
     }); 
    } 
} 

しかし、ビジーインジケータは、トリガされません。私は間違って何をしていますか?ありがとう。

+1

"インスタント"というメッセージを送信する動作を待っているだけなので、メッセージ受信がトリガするイベントを待つことはありません。私は、非同期RunReportメソッドでデータを取得することをお勧めし、それらの行に沿ったペイロードまたは何かとしてデータを含むメッセージを送信します。データを受信すると、データソースをロードします。それからあなたは期待どおりに待っているべきです。 –

+0

ありがとう、@マークW。あなたは答えのあなたのコメントを精巧に考えていますか? :) – Alex

答えて

2

あなたはそこにワットの全体のスープを持っています。

await Task.Run(() => 

のようなものは、あなたが本当に非同期/作品を待つ方法を理解していないお勧めします。私は降りて読んで素敵なドキュメンテーションを見つけました。また、あなたはUIスレッドですべての作業を行っているようです。

Dispatcher.Invoke((MethodInvoker)(() => { ReportViewer.RefreshReport(); })); 

UIを更新していない限り、バックグラウンドワーカーのディスパッチャーに触れてはいけません。 UIスレッドでバックグラウンドスレッド(レポートを更新する)で行う予定の実際の作業をオフロードしているようです。

多分あなたのレポートビューアはUIスレッドで実行する必要があります。そうだとしたら(多分前に設計されていて、マルチタスキングを利用していないかもしれません)、この状況についてはあまりできません。あなたのUIは処理中にロックされます。

長持ちするすべての作業をUIスレッドで実行する必要がある場合は、すべてのナンセンスを取り除きます。作業を開始する前に、IsBusyを更新してから、実行をオフ・ハンドラーReportViewer.RefreshReport()にディスパッチャーにオフロードしますが、低い優先度のDispatcherPriorityを使用して、UIが更新されてビジーであることを示します。あなたのUIは処理中に凍結されますが、少なくともあなたは何が起こっているのかをユーザーに示します。

+0

ありがとう、@ウィル。あなたは非同期/より良い学習を教えて私を指すことができる任意のドキュメント? – Alex

+1

@Alexは残念ながら誰もいません。 MSDNにはいくつかの良いものがありますが、検索ヒットのトップにはありません。私は実際にいくつかの側面を私の把握で幸せにしていないので、https://www.amazon.com/gp/product/1449367569/ref=ox_sc_sfl_title_1?ie=UTF8&psc=1&smid=ATVPDKIKX0DERが私のカートに座っているタスク。この本は、async/awaitについて学習するのに適しているようです。私は私の現在の読書を得るまでトリガーを引っ張っていないだけです.... – Will

関連する問題