Invoke command on a DataGridcolumn with single-click

99 Views Asked by At

I would like to create a hyperlink-column in wpf but rather with a command-binding instead of an uri.

 <DataGridTemplateColumn Header="{lex:Loc newmaterialnumber}" Width="*">
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <TextBlock TextDecorations="Underline" Text="{Binding NewMaterialnumber}"  Cursor="Hand" VerticalAlignment="Center" HorizontalAlignment="Left">
                            <TextBlock.InputBindings>
                                <MouseBinding MouseAction="LeftClick" Command="{Binding DataContext.OpenNewMaterialnumberCommand, RelativeSource={RelativeSource AncestorType={x:Type local:ArticleInfoSearchWindow}}}" />
                            </TextBlock.InputBindings>
                        </TextBlock>
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>

This works great but I have to select the row first before I can click the link. It would be achievable with a datatrigger which sets the row to selected on hover, but I don't really want do select the row on hover.

Any better ideas?

1

There are 1 best solutions below

0
Tommehh On BEST ANSWER

I came up with this solution. First of all create a new DataGridCommandColumn inherited by DataGridBoundColumn.

public class DataGridCommandColumn : DataGridBoundColumn
{
    [Bindable(true)]
    public ICommand Command
    {
        get => (ICommand)GetValue(CommandProperty);
        set => SetValue(CommandProperty, value);
    }

    public static readonly DependencyProperty CommandProperty = DependencyProperty.Register(
        nameof(Command),
        typeof(ICommand),
        typeof(DataGridCommandColumn));

    [Bindable(true)]
    public int FontSize
    {
        get => (int)GetValue(FontSizeProperty);
        set => SetValue(FontSizeProperty, value);
    }

    public static readonly DependencyProperty FontSizeProperty = DependencyProperty.Register(
        nameof(FontSize),
        typeof(int),
        typeof(DataGridCommandColumn));


    protected override FrameworkElement GenerateEditingElement(DataGridCell cell, object dataItem)
    {
        throw new NotImplementedException();
    }

    protected override FrameworkElement GenerateElement(DataGridCell cell, object dataItem)
    {
        var button = new Button();

        button.SetResourceReference(FrameworkElement.StyleProperty, "ToolButonWithDisabledRecognizesAccessKey");
        button.SetResourceReference(Control.ForegroundProperty, "PrimaryHueMidBrush");

        button.Height = 20;
        button.VerticalContentAlignment = VerticalAlignment.Top;
        button.HorizontalContentAlignment = HorizontalAlignment.Left;
        button.HorizontalAlignment = HorizontalAlignment.Left;
        button.Padding = new Thickness(0);
        button.FontWeight = FontWeights.Normal;
        if (FontSize != 0)
        {
            button.FontSize = FontSize;
        }


        button.Click += Button_Click;
        BindingOperations.SetBinding(button, ContentControl.ContentProperty, Binding);

        return button;
    }

    private void Button_Click(object sender, RoutedEventArgs e)
    {
        if (Command == null)
        {
            return;
        }

        if (Command.CanExecute(null))
        {
            Command.Execute(null);
        }
    }
}

Then create a proxy:

public class ViewModelProxy : Freezable
{
    protected override Freezable CreateInstanceCore()
    {
        return new ViewModelProxy();
    }

    public ViewModelBase ViewModel
    {
        get => (ViewModelBase)GetValue(ViewModelProperty);
        set => SetValue(ViewModelProperty, value);
    }

    public static readonly DependencyProperty ViewModelProperty = 
        DependencyProperty.Register("ViewModel", typeof(ViewModelBase), typeof(ViewModelProxy), new UIPropertyMetadata(null));
}

Later you can use it:

<utility:ViewModelProxy  x:Key="ViewModelProxy" ViewModel="{Binding}" />

<controls:DataGridCommandColumn Header="{lex:Loc submissionnumber}" Binding="{Binding SubmissionNumber}"  Command="{Binding ViewModel.OpenReceivableSubmissionNumberCommand,  Source={StaticResource ViewModelProxy}}" Width="Auto"  />