WPF MVVM bind Hyperlink RequestNavigate to View model
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
|
show 1 more comment
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
1
UseCommand
instead ofRequestNavigate
. 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 yourNavigateToTakePayment
command? The setter is only used when initialised, the UI will call thegetter
as it needs to callExecute
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 useRelayCommand
for myWPF
app. You need to initialize it in your Constructor and then the UI will call the backing filedsExecute(object parameter)
method.
– XAMlMAX
Mar 8 '16 at 10:51
|
show 1 more comment
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
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
c# wpf xaml mvvm hyperlink
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
UseCommand
instead ofRequestNavigate
. 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 yourNavigateToTakePayment
command? The setter is only used when initialised, the UI will call thegetter
as it needs to callExecute
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 useRelayCommand
for myWPF
app. You need to initialize it in your Constructor and then the UI will call the backing filedsExecute(object parameter)
method.
– XAMlMAX
Mar 8 '16 at 10:51
|
show 1 more comment
1
UseCommand
instead ofRequestNavigate
. 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 yourNavigateToTakePayment
command? The setter is only used when initialised, the UI will call thegetter
as it needs to callExecute
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 useRelayCommand
for myWPF
app. You need to initialize it in your Constructor and then the UI will call the backing filedsExecute(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
|
show 1 more comment
2 Answers
2
active
oldest
votes
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
add a comment |
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.
}
}
add a comment |
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
});
}
});
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
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
add a comment |
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
add a comment |
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
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
answered Mar 8 '16 at 11:00
XAMlMAXXAMlMAX
1,8751920
1,8751920
add a comment |
add a comment |
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.
}
}
add a comment |
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.
}
}
add a comment |
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.
}
}
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.
}
}
answered Nov 21 '18 at 15:18
ContangoContango
41.3k47189238
41.3k47189238
add a comment |
add a comment |
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.
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
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
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Post as a guest
Required, but never shown
Sign up or log in
StackExchange.ready(function () {
StackExchange.helpers.onClickDraftSave('#login-link');
});
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
Sign up using Google
Sign up using Facebook
Sign up using Email and Password
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
1
Use
Command
instead ofRequestNavigate
. 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 thegetter
as it needs to callExecute
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 myWPF
app. You need to initialize it in your Constructor and then the UI will call the backing filedsExecute(object parameter)
method.– XAMlMAX
Mar 8 '16 at 10:51