我知道我可以使用以下代码创建 RequestNavigate 事件的处理程序:
private static readonly ProcessStartInfo s_previewLinkProcessStartInfo = new() { UseShellExecute = true };
private void PreviewLink_RequestNavigate(object sender, System.Windows.Navigation.RequestNavigateEventArgs e)
{
s_previewLinkProcessStartInfo.FileName = e.Uri.AbsoluteUri;
using (Process.Start(s_previewLinkProcessStartInfo))
e.Handled = true;
}
上面的代码完美运行。但如果我使用相同的代码但使用命令,它将抛出 System.InvalidOperationException:“无法将资源转换为对象。”:
public ICommand PreviewLinkNavigateCommand => new RelayCommand(obj =>
{
s_previewLinkProcessStartInfo.FileName = PreviewLink.NavigateUri.AbsoluteUri;
using (Process.Start(s_previewLinkProcessStartInfo)) { } // throws a System.InvalidOperationException: "Failed to convert resource to object."
});
Xaml:
<TextBlock Padding="10 0 10 0">
<Hyperlink x:Name="PreviewLink" FontSize="14"
NavigateUri="{Binding SelectedMedia.Source.AbsoluteUri}"
Command="{Binding PreviewLinkNavigateCommand}">
Preview link
</Hyperlink>
</TextBlock>
中继命令:
internal class RelayCommand : ICommand
{
private readonly Action<object?> _execute;
private readonly Func<object?, bool>? _canExecute;
public event EventHandler? CanExecuteChanged
{
add => CommandManager.RequerySuggested += value;
remove => CommandManager.RequerySuggested -= value;
}
public RelayCommand(Action<object?> execute, Func<object?, bool>? canExecute = null)
{
_execute = execute;
_canExecute = canExecute;
}
public bool CanExecute(object? parameter) => _canExecute?.Invoke(parameter) ?? true;
public void Execute(object? parameter) => _execute(parameter);
}
这对您有用还是您不能直接将其写入 XAML? (以谷歌为例,但你也可以输入文件路径,它们就会工作)
XAML
<TextBlock Grid.Row="1" Grid.Column="2" HorizontalAlignment="Center" VerticalAlignment="Bottom" FontSize="18" FontWeight="Bold">
<Hyperlink RequestNavigate="Hyperlink_RequestNavigate"
NavigateUri="https://www.google.co.uk/">Google</Hyperlink>
</TextBlock>
背后代码
private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e) => Process.Start(e.Uri.AbsoluteUri);