同时,我完成了一个测试项目(在 VS 2022 中使用 .net 6.0),它的工作原理与前面描述的差不多。在转换器的 ConvertBack 部分抛出异常没有问题。唯一需要的区别是使用 Environment.ProcessPath 而不是 Application.ResourceAssembly.Location 重新启动程序:
主窗口.xaml:
<Window x:Class="TestStartWithButtonClick.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:TestStartWithButtonClick"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:MainViewModel, IsDesignTimeCreatable=True}"
SizeToContent="WidthAndHeight"
Title="MainWindow" >
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*" />
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TabControl Grid.Row="0" Grid.ColumnSpan="3">
<TabControl.Resources>
<local:StringMatchesParameterToBooleanConverter x:Key="StringMatchesParameterToBooleanConverter" />
</TabControl.Resources>
<TabItem x:Name="MyTab1" Header="MyTab1"
IsSelected="{Binding SelectedTabName, Converter={StaticResource StringMatchesParameterToBooleanConverter}, ConverterParameter=MyTab1}">
<StackPanel Width="300" Height="100" />
</TabItem>
<TabItem x:Name="MyTab2" Header="MyTab2"
IsSelected="{Binding SelectedTabName, Converter={StaticResource StringMatchesParameterToBooleanConverter}, ConverterParameter=MyTab2}">
<StackPanel Width="300" Height="100" />
</TabItem>
<TabItem x:Name="MyTab3" Header="MyTab3"
IsSelected="{Binding SelectedTabName, Converter={StaticResource StringMatchesParameterToBooleanConverter}, ConverterParameter=MyTab3}">
<StackPanel Width="300" Height="100" />
</TabItem>
</TabControl>
<Button Grid.Row="1" Grid.Column="0" Margin="0,0,6,0" Content="Start With Tab 1" Command="{Binding StartNewInstanceCommand}" CommandParameter="MyTab1"/>
<Button Grid.Row="1" Grid.Column="1" Margin="6,0,6,0" Content="Start With Tab 2" Command="{Binding StartNewInstanceCommand}" CommandParameter="MyTab2"/>
<Button Grid.Row="1" Grid.Column="2" Margin="6,0,0,0" Content="Start With Tab 3" Command="{Binding StartNewInstanceCommand}" CommandParameter="MyTab3"/>
</Grid>
</Window>
主窗口.xaml.cs
使用 System.Windows;
namespace TestStartWithButtonClick
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
DataContext = new MainViewModel();
}
}
}
主视图模型.cs:
using System;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Runtime.CompilerServices;
using System.Windows;
using System.Windows.Input;
namespace TestStartWithButtonClick
{
public class MainViewModel : INotifyPropertyChanged
{
private string _selectedTabName = string.Empty;
public event PropertyChangedEventHandler? PropertyChanged;
public MainViewModel()
{
var tabInfo = Environment.GetCommandLineArgs().FirstOrDefault(a => a.ToLower().StartsWith("/starttab="));
if (!string.IsNullOrWhiteSpace(tabInfo))
{
SelectedTabName = tabInfo.Substring(tabInfo.IndexOf('=') + 1);
}
else
{
SelectedTabName = "MyTab1";
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public StartNewInstanceCommand StartNewInstanceCommand { get; set; } = new();
public string SelectedTabName
{
get => _selectedTabName;
set
{
if (value == _selectedTabName) return;
_selectedTabName = value;
OnPropertyChanged(nameof(SelectedTabName));
}
}
}
public class StartNewInstanceCommand : ICommand
{
public bool CanExecute(object? parameter)
{
return true;
}
public void Execute(object? parameter)
{
if (parameter is not string tabItem)
throw new ArgumentException("parameter is not string", nameof(parameter));
Process.Start(Environment.ProcessPath, $"/StartTab={tabItem}");
Application.Current.Shutdown(0);
}
public event EventHandler? CanExecuteChanged;
}
}
StringMatchesParameterToBooleanConverter.cs:
using System;
using System.Diagnostics.CodeAnalysis;
using System.Globalization;
using System.Windows.Data;
namespace TestStartWithButtonClick
{
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();
}
}
}