WPF MVVM 绑定超链接RequestNavigate 到视图模型

问题描述 投票:0回答:3
c# wpf xaml mvvm hyperlink
3个回答
10
投票

HyperLink
是一个有点问题的孩子。不支持命令绑定。

可以使用附加属性将命令绑定支持硬塞到其中,但修改按钮来完成相同的操作会更容易。

<Style TargetType="Button" x:Key="HyperlinkStyledButton">
  <Setter Property="Template">
    <Setter.Value>
      <ControlTemplate TargetType="Button">
        <TextBlock Foreground="DodgerBlue"
                   Text="{TemplateBinding Content}"
                   TextDecorations="Underline" 
                   Cursor="Hand" />
      </ControlTemplate>
    </Setter.Value>
  </Setter>
</Style>

然后使用这样的超链接:

<Button Command="{Binding OpenHttpLinkCommand}" Content="www.google.com" 
        Style="{StaticResource HyperlinkStyledButton}" ToolTip="Some custom tooltip"/>

假设标准 MVVM 绑定工作正常:

在视图模型中:

public ICommand OpenHttpLinkCommand { get; }

在 ViewModel 构造函数中:

this.OpenHttpLinkCommand = new DelegateCommand(this.OnOpenHttpLinkCommand);

以及通过链接打开浏览器的命令:

private void OnOpenHttpLinkCommand()
{
    try
    {
        System.Diagnostics.Process.Start("http://www.google.com/");
    }
    catch (Exception)
    {
        // TODO: Error.
    }
}

7
投票

您的应用程序的问题是

ICommand
在使用前未初始化。我有一个像这样的命令实现:

public class RelayCommand : ICommand
    {
        Predicate<object> _canExecute;
        Action<object> _execute;
        bool _defaultBehaviourForCanExecute;

        public RelayCommand(Action<object> execute, bool defaultBehaviourForCanExecute = true, Predicate<object> canExecute = null)
        {
            _canExecute = canExecute;
            _execute = execute;
            _defaultBehaviourForCanExecute = defaultBehaviourForCanExecute;
        }

        public bool CanExecute(object parameter)
        {
            if (_canExecute != null)
            {
                Logger.LogInformation("Evaluating can execute method for " + _canExecute.Method.DeclaringType + "->"+_canExecute.Method.Name);
                return _canExecute.Invoke(parameter);
            }
            return _defaultBehaviourForCanExecute;
        }

        public event EventHandler CanExecuteChanged;

        public void RaiseCanExecuteChanged()
        {
            if (CanExecuteChanged != null)
                CanExecuteChanged(this, new EventArgs());
        }

        public void Execute(object parameter)
        {
            Logger.LogInformation("Executing command method for " + _execute.Method.DeclaringType + "->" + _execute.Method.Name);
            _execute.Invoke(parameter);
            RaiseCanExecuteChanged();
        }
    }

现在这正在我的

ViewModel
中初始化,如下所示:

NavigateToTakePayment = new RelayCommand(navigateToTakePayment CommandMethod);//it also can take canExecute method if you need a condition before executing.

然后在你的 xaml 中像这样使用它:

<Hyperlink RequestNavigate="{Binding Path=NavigateToTakePayment}" IsEnabled="{Binding CanTakePayment}">
    Launch Payments Portal
</Hyperlink>

顺便说一句:当您需要禁用超链接时,请实现

canexecute
方法,然后它会自动完成。


0
投票

旧线程,但对于那些像我一样仍然遇到它的人,

Hyperlink
确实支持
ICommandBinding
,但你需要一个派生类来这样做:

using System.Windows.Documents;

public class HyperlinkCommander : Hyperlink
{
    protected override void OnClick()
    {
        Command.Execute(null);
    }
}

然后在您的 xaml 中使用它,就像将

Button
绑定到 ViewModel 中的 ICommand 时一样,在本例中称为 HyperlinkClickerCommand。 像这样的东西:

<localControls:HyperlinkCommander Command="{Binding HyperlinkClickerCommand}" >
    Click me!
</localControls:HyperlinkCommander>

在 xaml 顶部附近有类似这样的内容:

<Window
    ... 
    xmlns:localControls="clr-namespace:TestProject.Controls"
    ...
>

其中

HyperlinkClickerCommand
是您要绑定到的 ViewModel 中的命令。 上面的超链接将触发绑定命令的 Execute,并遵守它的 CanExecute

© www.soinside.com 2019 - 2024. All rights reserved.