Search code examples
c#wpfxamlwindowupdating

Wpf Xaml view not updating


I have a splash screen that is supposed to show the loading process as the program starts up. I cannot get the text in the label to update as components are loaded.

From the main start-up program.cs I call the run() method in the splash screen controller.

startUpSplash.Run();

Here is the controller. This shows the splash screen with the label "Initializing..."

 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;
    }
}

Then from the main program.cs as different things are happening I call this UpdateStatus method also in the splash controller. This is meant to update the label to show all the different thing that are happening.

This is the Xaml for the lbl that is supposed to be getting updated.

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

The label is not updating when the UpdateStatus method is called. One strange thing I noticed was that if I did a

startupSplash.UpdateStatus("something");

and then

Messagebox.show("something"); 

The splash screen shows the updated label after the messagebox has popped up.

Any help with this would be appreciated.

UPDATE 2: Here is the View Model

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);
        }
    }
}

Solution

  • Here is how I ended up solving this.

    I added another method to the splashScreenController and called it from within UpdateStatus after setting the ViewModel.Status message.

     [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;
        }