2017-01-17 3 views
0

私は非常に簡単なことをしたいが、達成するのは非常に難しいと思う。View Modelがバインドされたデータを再ロードするときに 'Loading ...'オーバーレイを表示する方法

低速読み込み操作にバインドされているコンテンツがあるとします。たとえば、ローカルSQLから取得され、数秒かかる観察可能なリスト。これが起こっている間に、コンテンツのプレゼンター(例:Groupbox)を「読み込み中...」というテキストまたはその他の「待ってください」タイプのコンテンツにオーバーレイしたいとします。

操作の前後でUIにバインドされた論理フラグを単に切り替えるだけでは機能しないという結論に至りました。操作全体が完了するまで、UIは更新されません。たぶん、CPU集約型の操作なので、わかりません。

私は現在Adornerを探していますが、「ビジーインジケータ」オーバーレイのコンテキストでそれを検索するとほとんど情報が表示されません。約5年前からインターネット上にはほんの少しの解決策があり、私はそれらのいずれかを働かせることはできません。

質問:それは音として

として、単純な - 一時的に画面上に何かを表示する方法、ビューモデルは、バインドされたデータを更新するために働いている間に?

+0

トリガ幸せのMod閉じるために投票された - おそらく、この質問はとても簡単です、あなたは非常に明確に記述することができます1つまたは2つの文で解答するか? –

+0

booleanフラグは通知プロパティでしたか?それは裏付けのフィールドとプロパティを変更したプロパティ、通知を変更したプロパティでしたか? – Eric

答えて

1

操作の前後でUIにバインドされた論理フラグを単に切り替えるだけでは機能しないという結論に至りました。操作全体が完了するまで、UIは更新されません。たぶん、CPU集約型の操作なので、わかりません。

はい、実際には、バックグラウンドスレッドで長時間実行される操作を実行する必要があります。

以下の簡単な例を参照してください。

ビュー:

<Window x:Class="WpfApplication2.Window1" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
     xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
     xmlns:local="clr-namespace:WpfApplication2" 
     mc:Ignorable="d" 
     xmlns:s="clr-namespace:System;assembly=mscorlib" 
     Title="Window1" Height="300" Width="300"> 
    <Window.DataContext> 
     <local:Window1ViewModel /> 
    </Window.DataContext> 
    <Window.Resources> 
     <BooleanToVisibilityConverter x:Key="BooleanToVisibilityConverter" /> 
    </Window.Resources> 
    <Grid> 
     <TextBlock>Content...</TextBlock> 
     <Grid Background="Yellow" Visibility="{Binding IsLoading, Converter={StaticResource BooleanToVisibilityConverter}}"> 
      <TextBlock HorizontalAlignment="Center" VerticalAlignment="Center">Loading...</TextBlock> 
     </Grid> 
    </Grid> 
</Window> 

ビューモデル:

public class Window1ViewModel : INotifyPropertyChanged 
{ 
    public Window1ViewModel() 
    { 
     IsLoading = true; 
     //call the long running method on a background thread... 
     Task.Run(() => LongRunningMethod()) 
      .ContinueWith(task => 
      { 
       //and set the IsLoading property back to false back on the UI thread once the task has finished 
       IsLoading = false; 
      }, System.Threading.CancellationToken.None, TaskContinuationOptions.None, TaskScheduler.FromCurrentSynchronizationContext()); 
    } 

    public void LongRunningMethod() 
    { 
     System.Threading.Thread.Sleep(5000); 
    } 

    private bool _isLoading; 
    public bool IsLoading 
    { 
     get { return _isLoading; } 
     set { _isLoading = value; NotifyPropertyChanged(); } 
    } 

    public event PropertyChangedEventHandler PropertyChanged; 
    private void NotifyPropertyChanged([CallerMemberName] String propertyName = "") 
    { 
     if (PropertyChanged != null) 
      PropertyChanged(this, new PropertyChangedEventArgs(propertyName)); 
    } 
} 
1

ここでは、ViewModel \ Modelが長いタスクを処理しているときに、「読み込み中」表示でビューを設定する方法の例を示します。

ウィンドウ

<Window x:Class="Loading.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
    xmlns:local="clr-namespace:Loading" 
    mc:Ignorable="d" 
    Title="MainWindow" Height="350" Width="525"> 
<Window.Resources> 
    <local:VisibilityConverter x:Key="visibilityConverter" /> 
</Window.Resources> 
<Window.DataContext> 
    <local:ViewModel x:Name="viewModel" /> 
</Window.DataContext> 
<Grid> 
    <Button Content="Perform" VerticalAlignment="Bottom" HorizontalAlignment="Center" Width="100" Height="30" Command="{Binding HandleRequestCommand}" /> 
    <Border Visibility="{Binding Path=IsLoading,Converter={StaticResource visibilityConverter}}" Background="#AAAAAAAA" Margin="5"> 
     <TextBlock Text="Loading..." VerticalAlignment="Center" HorizontalAlignment="Center" /> 
    </Border> 
</Grid> 

VisibilityConverter.cs(単純なヘルパー・コンバータ)

class VisibilityConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     return (bool)value ? Visibility.Visible : Visibility.Collapsed; 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 
} 

ViewModel.cs

+0

ProgressRingを使用してisActiveプロパティをviewmodel作業プロパティにバインドするだけです。作業プロパティに変更通知があり、RaisePropertyChangedイベントが発生していることを確認してください。 例:IsActive = "{バインディングワーキング}" – SimperT

+0

基本的に、ソリューションはデータを別の 'Task'にロードし、そのタスクから' Dispatcher.CurrentDispatcher'経由でUIを更新します。 –

関連する問題