Search code examples
c#wpfmvvmtabcontroltabitem

How to open a specific tabitem on restart of WPF c# app on button click?


I have multiple tabitem's (tab1, tab2, ... etc) in a WPF tabcontrol. When I click a button I want to restart the app and open a specific tabitem, say tab2 (in MVVM friendly way).

To restart the app I use

            Process.Start(Application.ResourceAssembly.Location);
            Application.Current.Shutdown();

But how do I specify which tabitem to display after restart?


Solution

  • Obiously, your new app instance needs to "know something" about the requirement to open a specific tab item.

    There are other possiblities like creating a configuration file, but probably a command line parameter will serve well here. To start the new instance you may use something like Process.Start(Application.ResourceAssembly.Location, "/StartTab=MyTab3");

    Then, in your ViewModel, have a string property like public string SelectedTabName {get; set;} and initialize that during the construction of the VM:

    var tabInfo = Environment.GetCommandLineArgs().FirstOrDefault(a => a.ToLower().StartsWith("/starttab="));
    if (!string.IsNullOrWhiteSpace(tabInfo))
    {
        SelectedTabName = tabInfo.Substring(tabInfo.IndexOf('=')+1);
    }
    

    Finally, in the XAML code, bind the IsSelected property of your tab items to the SelectedTabName string, with the help of a StringToBooleanConverter, using the ConverterParameter like the name of the tab.

    public class StringMatchesParameterToBooleanConverter : IValueConverter
    {
        public object Convert( object value, Type targetType, object parameter, CultureInfo culture )
        {
            if (value is not string val)
                return false;
    
            if (parameter is not string param)
                return false;
    
            return val == param;
        }
    
        [ExcludeFromCodeCoverage]
        public object ConvertBack( object value, Type targetType, object parameter, CultureInfo culture )
        {
            throw new NotImplementedException();
        }
    }
    

    Your TabControl Xaml code could work like so

    <TabControl>
        <TabControl.Resources>
            <converters:StringMatchesParameterToBooleanConverter x:Key="StringMatchesParameterToBooleanConverter" />
        </TabControl.Resources>
        <TabItem x:Name="MyTab1"
                 IsSelected="{Binding SelectedTabName, Converter={StaticResource StringMatchesParameterToBooleanConverter}, ConverterParameter=MyTab1}">
        </TabItem>
        <TabItem x:Name="MyTab2"
                 IsSelected="{Binding SelectedTabName, Converter={StaticResource StringMatchesParameterToBooleanConverter}, ConverterParameter=MyTab2}">
        </TabItem>
        <TabItem x:Name="MyTab3"
                 IsSelected="{Binding SelectedTabName, Converter={StaticResource StringMatchesParameterToBooleanConverter}, ConverterParameter=MyTab3}">
        </TabItem>
    </TabControl>