简体   繁体   中英

Splash screen in WPF MVVM application

I have a MVVM WPF application from which I show a splash screen while some long task is done.

This splash screen is a typical WPF window and is very simple, it only has a label to show custom text such as "Loading..." and a spinner.

Its code-behind only has the constructor in which it is only performed the InitializeComponent and and event Window_Loaded.

From my main MVVM WPF application, when I perform a long task I instantiate this window and show the splash screen.

So now, I want to customize the text shown in the label in the splash screen. So what is the best approach?

What I have done is to pass as a parameter a string (custom message) to the constructor when I instantiate the window (Splash Screen).

Window mySplash = new SplashScreen("Loading or whatever I want");

As this splash screen is very simple, only a splash, I think it has no sense to apply MVVM here, so in the code-behind I create a private property which I set with the string passed as parameter to the constructor. Then, I bind the label in view with this private property and finally I implement INotifyPropertyChanged in the code-behind (view). There is no model, model view here.

Is that the correct way to do it? or is there any other way?

I know there is other solutions, like making public the label in the view by adding this:

x:FieldModifier="public"

and then access it once I instantiate the splash screen but I do not like this solution, I do not want to expose label outside.

ATTEMPT #1:

From my view model in main MVVM WPF application I perform below:

Window splashScreen = new SplashScreen("Loading ..."); 

Splash screen window:

<Window x:Class="My.Apps.WPF.SplashScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">

    <Grid>
    <!-- Grid row and column definitions here -->
         <Label Grid.Row="0" Content="{Binding Path=Message}"/>  
    </Grid>
</Window>

Splash screen code-behind:

public partial class SplashScreen: Window
{
    public string Message
    {
        get
        {
            return (string)GetValue(MessageProperty);
        }
        set { SetValue(MessageProperty, value); }
    }
    public static readonly DependencyProperty
        MessageProperty =
        DependencyProperty.Register("Message",
        typeof(string), typeof(System.Window.Controls.Label),
        new UIPropertyMetadata("Working, wait ..."));

    public SplashScreen(string message)
    {
        InitializeComponent();

        if (!String.IsNullOrEmpty(message))
            this.Message = message;
    }

}

I have set a default value for Label.It will be used if it is not passed as a parameter to the constructor.

It is not working, in the xaml preview is not showing the default message in the label in the Visual Studio IDE environment. Also for some reason, when I pass as a parameter the custom message from the view model, it is not shown in the label. What am I doing wrong?

You did not set DataContext for your grid:

<Window x:Class="My.Apps.WPF.SplashScreen"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    Name="Splash"
>

    <Grid DataContext="{Binding ElementName=Splash}">
    <!-- Grid row and column definitions here -->
         <Label Grid.Row="0" Content="{Binding Path=Message}"/>  
    </Grid>
</Window>

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM