WPF MVVM bind Hyperlink RequestNavigate to View model












3















On WPF form I have a hyperlink that when clicked is supposed aggregate some data in database before redirecting to internal web page.



Currently XAML looks following:



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


to do the db stuff Hyperlink_RequestNavigate method is used, that resides in View.xaml.cs



It looks something like:



private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
var transactionReference = GetToken(100M, "13215", "product");
var url = string.Format("{0}New?transactionReference={1}", Settings.Default.PaymentUrlWebsite, transactionReference);
e.Handled = true;
}


I don't like this mechanism being here and would prefer to move it to View model.



What I tried to do is add to ViewModel property



public ICommand NavigateToTakePayment       
{
get { return _navigateToTakePayment; }
set { _navigateToTakePayment = value; }
}


and in XAML change binding to



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


but it started giving me cast exceptions.



What is most appropriate way to move this mechanism from View to ViewModel?










share|improve this question




















  • 1





    Use Command instead of RequestNavigate. RequestNavigate is an event handler and it will expect code behind implementation, while command will expect Binding.

    – XAMlMAX
    Mar 8 '16 at 10:14













  • @XAMlMAX If I use command it runs fine and opens window without errors, but when I click on link nothing happens, it doesn't jump into setter.

    – Matas Vaitkevicius
    Mar 8 '16 at 10:17













  • How do you initialize your NavigateToTakePayment command? The setter is only used when initialised, the UI will call the getter as it needs to call Execute method on your Command. Hope this makes sense if not I will post an answer to aid my comments.

    – XAMlMAX
    Mar 8 '16 at 10:43











  • I am using backing fields that are nulls when initializing, do you think this is what's causing the issue of getter not being called on click?

    – Matas Vaitkevicius
    Mar 8 '16 at 10:49













  • Yes. I use RelayCommand for my WPF app. You need to initialize it in your Constructor and then the UI will call the backing fileds Execute(object parameter) method.

    – XAMlMAX
    Mar 8 '16 at 10:51
















3















On WPF form I have a hyperlink that when clicked is supposed aggregate some data in database before redirecting to internal web page.



Currently XAML looks following:



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


to do the db stuff Hyperlink_RequestNavigate method is used, that resides in View.xaml.cs



It looks something like:



private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
var transactionReference = GetToken(100M, "13215", "product");
var url = string.Format("{0}New?transactionReference={1}", Settings.Default.PaymentUrlWebsite, transactionReference);
e.Handled = true;
}


I don't like this mechanism being here and would prefer to move it to View model.



What I tried to do is add to ViewModel property



public ICommand NavigateToTakePayment       
{
get { return _navigateToTakePayment; }
set { _navigateToTakePayment = value; }
}


and in XAML change binding to



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


but it started giving me cast exceptions.



What is most appropriate way to move this mechanism from View to ViewModel?










share|improve this question




















  • 1





    Use Command instead of RequestNavigate. RequestNavigate is an event handler and it will expect code behind implementation, while command will expect Binding.

    – XAMlMAX
    Mar 8 '16 at 10:14













  • @XAMlMAX If I use command it runs fine and opens window without errors, but when I click on link nothing happens, it doesn't jump into setter.

    – Matas Vaitkevicius
    Mar 8 '16 at 10:17













  • How do you initialize your NavigateToTakePayment command? The setter is only used when initialised, the UI will call the getter as it needs to call Execute method on your Command. Hope this makes sense if not I will post an answer to aid my comments.

    – XAMlMAX
    Mar 8 '16 at 10:43











  • I am using backing fields that are nulls when initializing, do you think this is what's causing the issue of getter not being called on click?

    – Matas Vaitkevicius
    Mar 8 '16 at 10:49













  • Yes. I use RelayCommand for my WPF app. You need to initialize it in your Constructor and then the UI will call the backing fileds Execute(object parameter) method.

    – XAMlMAX
    Mar 8 '16 at 10:51














3












3








3


1






On WPF form I have a hyperlink that when clicked is supposed aggregate some data in database before redirecting to internal web page.



Currently XAML looks following:



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


to do the db stuff Hyperlink_RequestNavigate method is used, that resides in View.xaml.cs



It looks something like:



private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
var transactionReference = GetToken(100M, "13215", "product");
var url = string.Format("{0}New?transactionReference={1}", Settings.Default.PaymentUrlWebsite, transactionReference);
e.Handled = true;
}


I don't like this mechanism being here and would prefer to move it to View model.



What I tried to do is add to ViewModel property



public ICommand NavigateToTakePayment       
{
get { return _navigateToTakePayment; }
set { _navigateToTakePayment = value; }
}


and in XAML change binding to



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


but it started giving me cast exceptions.



What is most appropriate way to move this mechanism from View to ViewModel?










share|improve this question
















On WPF form I have a hyperlink that when clicked is supposed aggregate some data in database before redirecting to internal web page.



Currently XAML looks following:



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


to do the db stuff Hyperlink_RequestNavigate method is used, that resides in View.xaml.cs



It looks something like:



private void Hyperlink_RequestNavigate(object sender, RequestNavigateEventArgs e)
{
var transactionReference = GetToken(100M, "13215", "product");
var url = string.Format("{0}New?transactionReference={1}", Settings.Default.PaymentUrlWebsite, transactionReference);
e.Handled = true;
}


I don't like this mechanism being here and would prefer to move it to View model.



What I tried to do is add to ViewModel property



public ICommand NavigateToTakePayment       
{
get { return _navigateToTakePayment; }
set { _navigateToTakePayment = value; }
}


and in XAML change binding to



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


but it started giving me cast exceptions.



What is most appropriate way to move this mechanism from View to ViewModel?







c# wpf xaml mvvm hyperlink






share|improve this question















share|improve this question













share|improve this question




share|improve this question








edited Oct 12 '16 at 10:18









krlzlx

4,629143345




4,629143345










asked Mar 8 '16 at 10:01









Matas VaitkeviciusMatas Vaitkevicius

33.9k16167176




33.9k16167176








  • 1





    Use Command instead of RequestNavigate. RequestNavigate is an event handler and it will expect code behind implementation, while command will expect Binding.

    – XAMlMAX
    Mar 8 '16 at 10:14













  • @XAMlMAX If I use command it runs fine and opens window without errors, but when I click on link nothing happens, it doesn't jump into setter.

    – Matas Vaitkevicius
    Mar 8 '16 at 10:17













  • How do you initialize your NavigateToTakePayment command? The setter is only used when initialised, the UI will call the getter as it needs to call Execute method on your Command. Hope this makes sense if not I will post an answer to aid my comments.

    – XAMlMAX
    Mar 8 '16 at 10:43











  • I am using backing fields that are nulls when initializing, do you think this is what's causing the issue of getter not being called on click?

    – Matas Vaitkevicius
    Mar 8 '16 at 10:49













  • Yes. I use RelayCommand for my WPF app. You need to initialize it in your Constructor and then the UI will call the backing fileds Execute(object parameter) method.

    – XAMlMAX
    Mar 8 '16 at 10:51














  • 1





    Use Command instead of RequestNavigate. RequestNavigate is an event handler and it will expect code behind implementation, while command will expect Binding.

    – XAMlMAX
    Mar 8 '16 at 10:14













  • @XAMlMAX If I use command it runs fine and opens window without errors, but when I click on link nothing happens, it doesn't jump into setter.

    – Matas Vaitkevicius
    Mar 8 '16 at 10:17













  • How do you initialize your NavigateToTakePayment command? The setter is only used when initialised, the UI will call the getter as it needs to call Execute method on your Command. Hope this makes sense if not I will post an answer to aid my comments.

    – XAMlMAX
    Mar 8 '16 at 10:43











  • I am using backing fields that are nulls when initializing, do you think this is what's causing the issue of getter not being called on click?

    – Matas Vaitkevicius
    Mar 8 '16 at 10:49













  • Yes. I use RelayCommand for my WPF app. You need to initialize it in your Constructor and then the UI will call the backing fileds Execute(object parameter) method.

    – XAMlMAX
    Mar 8 '16 at 10:51








1




1





Use Command instead of RequestNavigate. RequestNavigate is an event handler and it will expect code behind implementation, while command will expect Binding.

– XAMlMAX
Mar 8 '16 at 10:14







Use Command instead of RequestNavigate. RequestNavigate is an event handler and it will expect code behind implementation, while command will expect Binding.

– XAMlMAX
Mar 8 '16 at 10:14















@XAMlMAX If I use command it runs fine and opens window without errors, but when I click on link nothing happens, it doesn't jump into setter.

– Matas Vaitkevicius
Mar 8 '16 at 10:17







@XAMlMAX If I use command it runs fine and opens window without errors, but when I click on link nothing happens, it doesn't jump into setter.

– Matas Vaitkevicius
Mar 8 '16 at 10:17















How do you initialize your NavigateToTakePayment command? The setter is only used when initialised, the UI will call the getter as it needs to call Execute method on your Command. Hope this makes sense if not I will post an answer to aid my comments.

– XAMlMAX
Mar 8 '16 at 10:43





How do you initialize your NavigateToTakePayment command? The setter is only used when initialised, the UI will call the getter as it needs to call Execute method on your Command. Hope this makes sense if not I will post an answer to aid my comments.

– XAMlMAX
Mar 8 '16 at 10:43













I am using backing fields that are nulls when initializing, do you think this is what's causing the issue of getter not being called on click?

– Matas Vaitkevicius
Mar 8 '16 at 10:49







I am using backing fields that are nulls when initializing, do you think this is what's causing the issue of getter not being called on click?

– Matas Vaitkevicius
Mar 8 '16 at 10:49















Yes. I use RelayCommand for my WPF app. You need to initialize it in your Constructor and then the UI will call the backing fileds Execute(object parameter) method.

– XAMlMAX
Mar 8 '16 at 10:51





Yes. I use RelayCommand for my WPF app. You need to initialize it in your Constructor and then the UI will call the backing fileds Execute(object parameter) method.

– XAMlMAX
Mar 8 '16 at 10:51












2 Answers
2






active

oldest

votes


















3














Problem with your app is that the ICommand is not initialized before use.

I have a Command implementation like so:



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();
}
}


Now this is being initialized in my ViewModel like so:



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


then in your xaml you use it like this:



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


BTW: when you Hyperlink needs to be disabled implement a canexecute method

and then it will be done automatically. If you need more info I will update my answer.

Happy coding






share|improve this answer































    1














    HyperLink is a bit of a problem child. It does not support command binding.



    It's possible to shoehorn support for command binding into it with an attached property, but it's easier to just modify a button to do the same thing.



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




    Then use the hyperlink:



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


    Assuming that standard MVVM binding is working correctly:



    In the ViewModel:



    public ICommand OpenHttpLinkCommand { get; }


    In the ViewModel constructor:



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


    And the command to open the browser with a link:



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





    share|improve this answer























      Your Answer






      StackExchange.ifUsing("editor", function () {
      StackExchange.using("externalEditor", function () {
      StackExchange.using("snippets", function () {
      StackExchange.snippets.init();
      });
      });
      }, "code-snippets");

      StackExchange.ready(function() {
      var channelOptions = {
      tags: "".split(" "),
      id: "1"
      };
      initTagRenderer("".split(" "), "".split(" "), channelOptions);

      StackExchange.using("externalEditor", function() {
      // Have to fire editor after snippets, if snippets enabled
      if (StackExchange.settings.snippets.snippetsEnabled) {
      StackExchange.using("snippets", function() {
      createEditor();
      });
      }
      else {
      createEditor();
      }
      });

      function createEditor() {
      StackExchange.prepareEditor({
      heartbeatType: 'answer',
      autoActivateHeartbeat: false,
      convertImagesToLinks: true,
      noModals: true,
      showLowRepImageUploadWarning: true,
      reputationToPostImages: 10,
      bindNavPrevention: true,
      postfix: "",
      imageUploader: {
      brandingHtml: "Powered by u003ca class="icon-imgur-white" href="https://imgur.com/"u003eu003c/au003e",
      contentPolicyHtml: "User contributions licensed under u003ca href="https://creativecommons.org/licenses/by-sa/3.0/"u003ecc by-sa 3.0 with attribution requiredu003c/au003e u003ca href="https://stackoverflow.com/legal/content-policy"u003e(content policy)u003c/au003e",
      allowUrls: true
      },
      onDemand: true,
      discardSelector: ".discard-answer"
      ,immediatelyShowMarkdownHelp:true
      });


      }
      });














      draft saved

      draft discarded


















      StackExchange.ready(
      function () {
      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35864275%2fwpf-mvvm-bind-hyperlink-requestnavigate-to-view-model%23new-answer', 'question_page');
      }
      );

      Post as a guest















      Required, but never shown

























      2 Answers
      2






      active

      oldest

      votes








      2 Answers
      2






      active

      oldest

      votes









      active

      oldest

      votes






      active

      oldest

      votes









      3














      Problem with your app is that the ICommand is not initialized before use.

      I have a Command implementation like so:



      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();
      }
      }


      Now this is being initialized in my ViewModel like so:



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


      then in your xaml you use it like this:



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


      BTW: when you Hyperlink needs to be disabled implement a canexecute method

      and then it will be done automatically. If you need more info I will update my answer.

      Happy coding






      share|improve this answer




























        3














        Problem with your app is that the ICommand is not initialized before use.

        I have a Command implementation like so:



        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();
        }
        }


        Now this is being initialized in my ViewModel like so:



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


        then in your xaml you use it like this:



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


        BTW: when you Hyperlink needs to be disabled implement a canexecute method

        and then it will be done automatically. If you need more info I will update my answer.

        Happy coding






        share|improve this answer


























          3












          3








          3







          Problem with your app is that the ICommand is not initialized before use.

          I have a Command implementation like so:



          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();
          }
          }


          Now this is being initialized in my ViewModel like so:



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


          then in your xaml you use it like this:



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


          BTW: when you Hyperlink needs to be disabled implement a canexecute method

          and then it will be done automatically. If you need more info I will update my answer.

          Happy coding






          share|improve this answer













          Problem with your app is that the ICommand is not initialized before use.

          I have a Command implementation like so:



          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();
          }
          }


          Now this is being initialized in my ViewModel like so:



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


          then in your xaml you use it like this:



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


          BTW: when you Hyperlink needs to be disabled implement a canexecute method

          and then it will be done automatically. If you need more info I will update my answer.

          Happy coding







          share|improve this answer












          share|improve this answer



          share|improve this answer










          answered Mar 8 '16 at 11:00









          XAMlMAXXAMlMAX

          1,8751920




          1,8751920

























              1














              HyperLink is a bit of a problem child. It does not support command binding.



              It's possible to shoehorn support for command binding into it with an attached property, but it's easier to just modify a button to do the same thing.



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




              Then use the hyperlink:



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


              Assuming that standard MVVM binding is working correctly:



              In the ViewModel:



              public ICommand OpenHttpLinkCommand { get; }


              In the ViewModel constructor:



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


              And the command to open the browser with a link:



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





              share|improve this answer




























                1














                HyperLink is a bit of a problem child. It does not support command binding.



                It's possible to shoehorn support for command binding into it with an attached property, but it's easier to just modify a button to do the same thing.



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




                Then use the hyperlink:



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


                Assuming that standard MVVM binding is working correctly:



                In the ViewModel:



                public ICommand OpenHttpLinkCommand { get; }


                In the ViewModel constructor:



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


                And the command to open the browser with a link:



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





                share|improve this answer


























                  1












                  1








                  1







                  HyperLink is a bit of a problem child. It does not support command binding.



                  It's possible to shoehorn support for command binding into it with an attached property, but it's easier to just modify a button to do the same thing.



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




                  Then use the hyperlink:



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


                  Assuming that standard MVVM binding is working correctly:



                  In the ViewModel:



                  public ICommand OpenHttpLinkCommand { get; }


                  In the ViewModel constructor:



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


                  And the command to open the browser with a link:



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





                  share|improve this answer













                  HyperLink is a bit of a problem child. It does not support command binding.



                  It's possible to shoehorn support for command binding into it with an attached property, but it's easier to just modify a button to do the same thing.



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




                  Then use the hyperlink:



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


                  Assuming that standard MVVM binding is working correctly:



                  In the ViewModel:



                  public ICommand OpenHttpLinkCommand { get; }


                  In the ViewModel constructor:



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


                  And the command to open the browser with a link:



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






                  share|improve this answer












                  share|improve this answer



                  share|improve this answer










                  answered Nov 21 '18 at 15:18









                  ContangoContango

                  41.3k47189238




                  41.3k47189238






























                      draft saved

                      draft discarded




















































                      Thanks for contributing an answer to Stack Overflow!


                      • Please be sure to answer the question. Provide details and share your research!

                      But avoid



                      • Asking for help, clarification, or responding to other answers.

                      • Making statements based on opinion; back them up with references or personal experience.


                      To learn more, see our tips on writing great answers.




                      draft saved


                      draft discarded














                      StackExchange.ready(
                      function () {
                      StackExchange.openid.initPostLogin('.new-post-login', 'https%3a%2f%2fstackoverflow.com%2fquestions%2f35864275%2fwpf-mvvm-bind-hyperlink-requestnavigate-to-view-model%23new-answer', 'question_page');
                      }
                      );

                      Post as a guest















                      Required, but never shown





















































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown

































                      Required, but never shown














                      Required, but never shown












                      Required, but never shown







                      Required, but never shown







                      Popular posts from this blog

                      Biblatex bibliography style without URLs when DOI exists (in Overleaf with Zotero bibliography)

                      ComboBox Display Member on multiple fields

                      Is it possible to collect Nectar points via Trainline?