8

Is there any way I can associate a Command with a DataGridHyperlinkColumn? I've tried this:

   <DataGridHyperlinkColumn Header="Client Name" Binding="{Binding ShortName}">
     <DataGridHyperlinkColumn.ElementStyle>
      <Style TargetType="TextBlock">
       <Setter Property="Hyperlink.Command" 
                                    Value="{Binding DataContext.NavigateToClientCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:ClientsSummaryView}}}"/>
                            <Setter Property="Hyperlink.CommandParameter" Value="{Binding}"/>
                        </Style>
                    </DataGridHyperlinkColumn.ElementStyle>
    </DataGridHyperlinkColumn>

At runtime, I can see that the binding is being correctly evaluated (the property getter for the Command is called), but the Command is not executed when I click the hyperlink. Is there a better way to do this?

Thanks,

Daniel

2 Answers 2

13

Are you sure the command is being associated with the hyperlink? I tried setting this up in a sample app, and the command wasn't being associated with the hyperlink (if you return false from CanExecute, you'll be able to quickly determine if it is wired up).

Instead, I created a DataGridTemplateColumn to accomplish this:

<DataGridTemplateColumn Header="Client Name">
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <TextBlock>
                <Hyperlink Command="{Binding DataContext.NavigateToClientCommand, RelativeSource={RelativeSource AncestorType={x:Type local:ClientsSummaryView}}}"
                           CommandParameter="{Binding ShortName}">
                     <TextBlock Text="{Binding ShortName}" />
                </Hyperlink>
            </TextBlock>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

This would get really annoying if you had to create multiple columns. After cracking open the Toolkit with Reflector, it looks like it is supporting the TargetName / NavigationUrl paradigm for using the hyperlink.

If you have a scenario where you would require this type of column in many places, I would suggest extending the DataGridHyperlinkColumn and adding a Command property. You could then modify the element returned from GenerateElement so that it used your command.

Sign up to request clarification or add additional context in comments.

3 Comments

Abe: thanks. I was hoping to shortcut around DataGridTemplateColumn, but, honestly, it doesn't look much worse than what I had. Thanks again!
Can you explain how the <Hyperlink Command="{Binding..."> works? It looks very complicated.
@Dai - this is a RelativeSource binding to an ICommand property on the DataContext of the ClientsSummaryView where this column is added. This question asked about these types of bindings, and hopefully will help you understand it better: stackoverflow.com/questions/84278/…
2

Yes, but not with the standard DataGridHyperlinkColumn. You need to enhance that class a little.

public class DataGridHyperlinkColumn : System.Windows.Controls.DataGridHyperlinkColumn
{
    /// <summary>
    /// Support binding the hyperlink to an ICommand rather than a Uri
    /// </summary>
    public BindingBase CommandBinding { get; set; }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        var result = base.GenerateElement(cell, dataItem);

        if (((TextBlock)result).Inlines.FirstInline is Hyperlink link)
            BindingOperations.SetBinding(link, Hyperlink.CommandProperty, CommandBinding);

        return result;
    }
}

After setting up the correct namespace mapping you can then do this:

<c:DataGridHyperlinkColumn Header="Booking" Binding="{Binding Path=ReservationNo}" CommandBinding="{Binding Path=NavigateCommand}" />

This assumes that NavigateCommand exists on your viewmodel object.

Comments

Your Answer

By clicking “Post Your Answer”, you agree to our terms of service and acknowledge you have read our privacy policy.

Start asking to get answers

Find the answer to your question by asking.

Ask question

Explore related questions

See similar questions with these tags.