wpf/xaml styling of a hyperlink that doesn't open the link but rather copies it to clipboard

166 Views Asked by At

I have a program that retrieves articles from the web, and basically needs to display all of them in a list with custom items that have the article id, title, uri, views and so on. I want to unite the article title and uri into a hyperlink, so that I see the title, and the path will be the uri, sounds like a simple hyperlink, however, instead of opening the link straight away in my browser when I click on it, I just want it to copy the link to my clipboard, that much, I wasn't able to figure out how to do, if it just once, I could easily do it from the code and handler, but because it's in a list, I need it completely configured from xaml. here is the code, I will split it so that you can see exactly where is the hyperlink the listItem style, if you can think of a way, that would be amazing.

<Style x:Key="ArticleListboxItem" TargetType="ListBoxItem">
    <Setter Property="SnapsToDevicePixels" Value="True" />
    <Setter Property="OverridesDefaultStyle" Value="True" />
    <Setter Property="BorderThickness" Value="0"/>
    <Setter Property="Foreground" Value="White" />
    <Setter Property="FontFamily" Value="{StaticResource DefaultFont}" />
    <Setter Property="FontWeight" Value="Regular" />
    <Setter Property="FontSize" Value="16" />
    <Setter Property="UseLayoutRounding" Value="True" />
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="ListBoxItem">
                <Border x:Name="Border" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Padding="3" Background="{TemplateBinding Background}" BorderThickness="0" SnapsToDevicePixels="true">
                    <Grid Background="{TemplateBinding Background}" HorizontalAlignment="Stretch" UseLayoutRounding="{TemplateBinding UseLayoutRounding}" Visibility="Visible">
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="Auto" />
                            <ColumnDefinition Width="1*" />
                            <ColumnDefinition Width="1*" />
                        </Grid.ColumnDefinitions>
                        <Grid Grid.Column="0"/> <!--Just a spacer-->>
                        <Label Name="lblArticleId" Grid.Column="1" Content="{Binding Path=ArticleID}" Foreground="White" HorizontalContentAlignment="Left" FontSize="14"/>

This is the part I need help with, the code isn't correct but more to show the structure without any of my failed attempts to interfere (and by failed I mean I wasn't event close)

<Hyperlink Name="linkArticle" Grid.Column="2" Text="{Binding Path=ArticleTitle}" Link="{Binding Path=ArticleLink}"/>

And the rest of listItem style:

                        <Label Name="lblViews" Grid.Column="3" Content="{Binding Path=ArticleViews}" Foreground="White" HorizontalContentAlignment="Right" FontSize="14"/>
                        <Label Name="lblDate" Grid.Column="4" Content="{Binding Path=ArticleDate}" Foreground="White" HorizontalContentAlignment="Right" FontSize="14"/>
                    </Grid>
                </Border>
                <ControlTemplate.Triggers>
                    <!--Some color modifications that are irrelevant, like change foreground when mouse is over-->
                </ControlTemplate.Triggers>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>
1

There are 1 best solutions below

5
BionicCode On

The following snippet shows a hyperlink that copies the Hyperlink.NavigateUri to the Windows clipboard when clicked:

<TextBlock>
  <Hyperlink NavigateUri="{Binding ArticleLink}" 
             Click="CopyUriToClipboard_OnHyperlinkClicked">
    <Run Text="{Binding ArticleTitle}" />
  </Hyperlink>
</TextBlock>

private void CopyUriToClipboard_OnHyperlinkClicked(object sender, RoutedEventArgs e)
{
  var hyperlink = sender as Hyperlink;
  Clipboard.SetText(hyperlink.NavigateUri.ToString(), TextDataFormat.Text);
}