jan kowalski
jan kowalski

Reputation: 199

Modify text in column cells and make it hyperlink, listView WPF C#

For now I am displaying in one of the columns in listView, GridView one of the property of my class. This looks more or less:

    <ListView x:Name="offers_listView"  Margin="38,185,35,81" >
        <ListView.View>
            <GridView>
                <GridViewColumn Width="100" Header="itemId" DisplayMemberBinding="{Binding Path=itemId}" />

ItemID is a number.

What I would like to do is make a hyperlink based on this number. For example from ItemId equals to 1234 I would like to make clickable link to address www.website.com/showItem.php?itemId=1234. The best solution would be if the column still display 1234 but it is clickable link to the address I mentioned. Of course for the whole list, each item have different itemID property.

May anyone give me a hint how to do it or sample of code I can based ?

edit:

Solution gave below have been adapted by me.

However on the logic side NavigateUri have been null, so the link opened in browser have been not correct. I have adapt this idea directly to textblock as I paste my code below:

                <GridViewColumn Width="100" Header="itemLink">
                    <GridViewColumn.CellTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Path=itemId}" MouseDown="TextBlock_MouseDown"/>
                        </DataTemplate>
                    </GridViewColumn.CellTemplate>
                </GridViewColumn>

    private void TextBlock_MouseDown(object sender, MouseButtonEventArgs e)
    {
        var urlPart2 = ((TextBlock)sender).Text;
        //var urlPart = ((Hyperlink)sender).NavigateUri;
        var fullUrl = string.Format("http://allegro.pl/show_item.php?item={0}", urlPart2);
        Process.Start(new ProcessStartInfo(fullUrl));
        e.Handled = true;
    }

Upvotes: 2

Views: 3055

Answers (2)

ASh
ASh

Reputation: 35703

I have created a reusable command for situations when application has to open a webpage in browser:

public class BrowseCommand : ICommand
{
    public virtual void Execute(object parameter)
    {
        var path = parameter as string;
        if (String.IsNullOrWhiteSpace(path) == false)
        {
            // if path is URL, start browser with selected page
            Process.Start(new ProcessStartInfo(path));
        }
    }

    public virtual bool CanExecute(object parameter)
    {
        var path = parameter as string;
        return !String.IsNullOrWhiteSpace(path);
    }

    public event EventHandler CanExecuteChanged
    {
        add { CommandManager.RequerySuggested += value; }
        remove { CommandManager.RequerySuggested -= value; }
    }

    protected virtual void OnCanExecuteChanged(EventArgs e)
    {
        CommandManager.InvalidateRequerySuggested();
    }
}

BrowseCommand requires URL as parameter. I suggest to extend view model and declare url property (based on Id) there, e.g.

public class ItemVm
{
    public int ItemId { get; set; }

    public string ItemUrl
    {
        get { return String.Format("http://stackoverflow.com/questions/{0}", ItemId); }
    }
}

the final step is to customize view. after adding BrowseCommand to Resources, I modified CellTemplate (text with underline) and attached middle mouse click command:

<ListView x:Name="offers_listView" Grid.Row="1" ItemsSource="{Binding Path=List}">
    <ListView.Resources>
        <local:BrowseCommand x:Key="BrowseCmd"/>
    </ListView.Resources>
    <ListView.View>
        <GridView>
            <GridViewColumn Width="100" Header="ItemId">
                <GridViewColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding Path=ItemId}" 
                                   Cursor="Hand" TextDecorations="Underline">
                            <TextBlock.InputBindings>
                                <MouseBinding Gesture="MiddleClick" 
                                              Command="{StaticResource BrowseCmd}" 
                                              CommandParameter="{Binding Path=ItemUrl}"/>
                            </TextBlock.InputBindings>
                        </TextBlock>
                    </DataTemplate>
                </GridViewColumn.CellTemplate>
            </GridViewColumn>
        </GridView>
    </ListView.View>
</ListView>

Upvotes: 2

zastrowm
zastrowm

Reputation: 8243

You need to change the cell template for the GridViewColumn in order to have the column contain hyperlinks.

For example, the following:

<GridViewColumn.CellTemplate>
  <DataTemplate>
    <TextBlock>
      <Hyperlink NavigateUri="{Binding Path=itemId}" RequestNavigate="Hyperlink_OnRequestNavigate">
        <TextBlock Text="{Binding Path=itemId}"/>
      </Hyperlink>
    </TextBlock>
  </DataTemplate>
</GridViewColumn.CellTemplate>

will have the given column filled with hyperlinks. WPF doesn't do anything with hyperlinks by default, so you have to add a handler yourself that opens the link:

private void Hyperlink_OnRequestNavigate(object sender, RequestNavigateEventArgs e)
{
  var urlPart = ((Hyperlink)sender).NavigateUri;
  var fullUrl = string.Format("http://www.website.com/showItem.php?itemId={0}", urlPart);
  Process.Start(new ProcessStartInfo(fullUrl));
  e.Handled = true;
}

Of course, change the url to do whatever you want to do.

Upvotes: 4

Related Questions