WPF Core Hyperlkink Custom Control
-
I'm trying to create what I thought would be a simple custom control to implement a hyperlink. This all works in WPF .Net Framework, but in .Net Core I have 2 problems. First, here's the code: XAML
<Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <TextBlock> <Hyperlink> <TextBlock Text="{Binding LinkText}"/> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding LinkClickedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Hyperlink> </TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter>
Code Behind
using Marois.Framework.Core.Utilities;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;namespace MaroisHyperlink
{
public class MaroisHyperlink : Control
{
#region Commands
private ICommand? _LinkClickedCommand;
public ICommand LinkClickedCommand
{
get
{
if (_LinkClickedCommand == null)
_LinkClickedCommand = new RelayCommand(LinkClickedExecuted, LinkClickedCanExecute);
return _LinkClickedCommand;
}
}
#endregion#region DP LinkText public static readonly DependencyProper
-
I'm trying to create what I thought would be a simple custom control to implement a hyperlink. This all works in WPF .Net Framework, but in .Net Core I have 2 problems. First, here's the code: XAML
<Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <TextBlock> <Hyperlink> <TextBlock Text="{Binding LinkText}"/> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{Binding LinkClickedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Hyperlink> </TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter>
Code Behind
using Marois.Framework.Core.Utilities;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;namespace MaroisHyperlink
{
public class MaroisHyperlink : Control
{
#region Commands
private ICommand? _LinkClickedCommand;
public ICommand LinkClickedCommand
{
get
{
if (_LinkClickedCommand == null)
_LinkClickedCommand = new RelayCommand(LinkClickedExecuted, LinkClickedCanExecute);
return _LinkClickedCommand;
}
}
#endregion#region DP LinkText public static readonly DependencyProper
You're binding to a property defined in the code-behind of the control. But the
DataContext
isn't set anywhere, so it will be inherited from the parent. You'll need to use aTemplateBinding
to bind to the control's properties:<Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <TextBlock> <Hyperlink> <TextBlock Text="{TemplateBinding LinkText}"/> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{TemplateBinding LinkClickedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Hyperlink> </TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter>
The Interaction markup looks correct to me. I can't see any reason for that not to compile, unless the NuGet package reference isn't loading correctly. It may be worth raising an issue on the GitHub project for that library[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
-
You're binding to a property defined in the code-behind of the control. But the
DataContext
isn't set anywhere, so it will be inherited from the parent. You'll need to use aTemplateBinding
to bind to the control's properties:<Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <TextBlock> <Hyperlink> <TextBlock Text="{TemplateBinding LinkText}"/> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{TemplateBinding LinkClickedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Hyperlink> </TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter>
The Interaction markup looks correct to me. I can't see any reason for that not to compile, unless the NuGet package reference isn't loading correctly. It may be worth raising an issue on the GitHub project for that library[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Richard Deeming wrote:
<TextBlock Text="{TemplateBinding LinkText}"/>
This doesn't compile with the error "The member "LinkText" is not recognized or is not accessible." LinkText is a DP I created in the class file.
If it's not broken, fix it until it is. Everything makes sense in someone's mind. Ya can't fix stupid.
-
You're binding to a property defined in the code-behind of the control. But the
DataContext
isn't set anywhere, so it will be inherited from the parent. You'll need to use aTemplateBinding
to bind to the control's properties:<Setter Property="Template"> <Setter.Value> <ControlTemplate> <Border Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}"> <TextBlock> <Hyperlink> <TextBlock Text="{TemplateBinding LinkText}"/> <i:Interaction.Triggers> <i:EventTrigger EventName="Click"> <i:InvokeCommandAction Command="{TemplateBinding LinkClickedCommand}"/> </i:EventTrigger> </i:Interaction.Triggers> </Hyperlink> </TextBlock> </Border> </ControlTemplate> </Setter.Value> </Setter>
The Interaction markup looks correct to me. I can't see any reason for that not to compile, unless the NuGet package reference isn't loading correctly. It may be worth raising an issue on the GitHub project for that library[^].
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer
Had to add the RelativeSource:
However that doesn't seem to work in the command (For some reason the command code now compiles):
with
The property 'RelativeSource' was not found in type 'TemplateBindingExtension'.
If it's not broken, fix it until it is. Everything makes sense in someone's mind. Ya can't fix stupid.
-
Had to add the RelativeSource:
However that doesn't seem to work in the command (For some reason the command code now compiles):
with
The property 'RelativeSource' was not found in type 'TemplateBindingExtension'.
If it's not broken, fix it until it is. Everything makes sense in someone's mind. Ya can't fix stupid.
{TemplateBinding x}
should be equivalent to{Binding x, RelativeSource={RelativeSource TemplatedParent}}
. The error is telling you that you can't set aRelativeSource
on aTemplateBinding
.
"These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer