1

プログラムの起動時に読み込みプロセスを表示するスプラッシュ スクリーンがあります。コンポーネントが読み込まれると、ラベルのテキストを更新することができません。

メインのスタートアップ program.cs から、スプラッシュ スクリーン コントローラーで run() メソッドを呼び出します。

startUpSplash.Run();

こちらがコントローラー。これは、「初期化中...」というラベルが付いたスプラッシュ スクリーンを示しています。

 public class StartUpSplashController
{
    public StartUpSplashViewModel ViewModel { get; set; }

    private StartUpSplashView starUpSplashWindow = new StartUpSplashView();
    private delegate void UIDelegate();
    public void Run()
    {
        InitializeViewModel();

        ViewModel.StatusMessage = "Initializing...";

        starUpSplashWindow.DataContext = ViewModel;
        starUpSplashWindow.Show();
    }



    public void UpdateStatus(string statusMessage)
    {
        starUpSplashWindow.Dispatcher.Invoke(new UIDelegate(delegate { ViewModel.StatusMessage = statusMessage; }));
        //ViewModel.StatusMessage = statusMessage;
    }

    public void End()
    {
        starUpSplashWindow.Close();
        starUpSplashWindow.InvalidateVisual();
    }

    private void InitializeViewModel()
    {
        ViewModel = new StartUpSplashViewModel(starUpSplashWindow);
        ViewModel.Controller = this;
    }
}

次に、メインの program.cs から、さまざまなことが起こっているときに、スプラッシュ コントローラーでもこの UpdateStatus メソッドを呼び出します。これは、ラベルを更新して、起こっているさまざまなことをすべて表示することを目的としています。

これは、更新されるはずの lbl の Xaml です。

 <Label Content="{Binding Path=StatusMessage, Mode=TwoWay, UpdateSourceTrigger= PropertyChanged}"  />

UpdateStatus メソッドが呼び出されたときに、ラベルが更新されていません。私が気づいた奇妙なことの1つは、

startupSplash.UpdateStatus("something");

その後

Messagebox.show("something"); 

メッセージボックスがポップアップした後、スプラッシュ画面に更新されたラベルが表示されます。

これについての助けをいただければ幸いです。

更新 2: ビュー モデルは次のとおりです。

public class StartUpSplashViewModel : ViewModel<IView>
{
    [ImportingConstructor]
    public StartUpSplashViewModel(StartUpSplashView view)
        : base(view)
    {
    }

    public StartUpSplashController Controller { get; set; }

    private string _statusMessage;
    public string StatusMessage
    {
        get
        {
            return _statusMessage;
        }
        set
        {
            if (_statusMessage == value)
                return;

            _statusMessage = value;
            this.RaisePropertyChanged(s => s.StatusMessage);
        }
    }
}
4

3 に答える 3

1

スプラッシュ ウィンドウの実行中の UI スレッドに更新を入れてみましたか? これを行うには、Dispatcher.Invoke メソッドを使用できます。まず、デリゲートを宣言する必要があります。

private delegate void UIDelegate();

次に、そのデリゲートを Dispatcher で使用します。

starUpSplashWindow.Dispatcher.Invoke(new UIDelegate(delegate
{
    ViewModel.StatusMessage = statusMessage;
}));

これにより、UI を実行しているスレッドで更新が呼び出され、通常は UI が適切に更新されます。

于 2011-11-15T20:26:12.033 に答える
0

これが私がこれを解決した方法です。

SplashScreenController に別のメソッドを追加し、ViewModel.Status メッセージを設定した後、UpdateStatus 内から呼び出しました。

 [SecurityPermissionAttribute(SecurityAction.Demand, Flags = SecurityPermissionFlag.UnmanagedCode)]
    public void DoEvents()
    {
        DispatcherFrame frame = new DispatcherFrame();
        Dispatcher.CurrentDispatcher.BeginInvoke(DispatcherPriority.Background,
            new DispatcherOperationCallback(ExitFrame), frame);
        Dispatcher.PushFrame(frame);
    }

    public object ExitFrame(object f)
    {
        ((DispatcherFrame)f).Continue = false;

        return null;
    }
于 2011-11-16T20:34:21.430 に答える
0

私は試していないので、これがうまくいくかどうかはわかりませんが、うまくいくことを願っています。

次のように、SplashWindow.xaml.cs ビュー ファイル内にRefreshDelegateandメソッドを作成します。Refresh

// To Refresh the UI immediately
private delegate void RefreshDelegate();
private static void Refresh(DependencyObject obj)
{
    obj.Dispatcher.Invoke(System.Windows.Threading.DispatcherPriority.Render,
        (RefreshDelegate)delegate { });
}

UpdateStatusController のメソッドを次のように変更します。

public void UpdateStatus(string statusMessage)
{    
    ViewModel.StatusMessage = statusMessage;
    starUpSplashWindow.Refresh(starUpSplashWindow.statusLabel); //where statusLabel is the name of the Label
}
于 2011-11-16T05:58:47.870 に答える