This is a migrated thread and some comments may be shown as answers.

Bind Double Click to a ViewModel Command

19 Answers 1954 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Jon
Top achievements
Rank 1
Jon asked on 08 Jun 2009, 02:25 PM
Is there a way to bind the double click command of a RadGridView to a command on the ViewModel instead of to an event?

<Controls:RadGridView.InputBindings> 
    <MouseBinding Gesture="LeftDoubleClick" Command="{Binding RecipeSelectedCommand}"/>  
</Controls:RadGridView.InputBindings> 
 


I'm getting

System.Windows.Markup.XamlParseException occurred
  Message="A 'Binding' cannot be set on the 'Command' property of type 'MouseBinding'. A 'Binding' can only be set on a DependencyProperty of a DependencyObject."
  Source="PresentationFramework"
  LineNumber=0
  LinePosition=0
  StackTrace:
       at MS.Internal.Helper.CheckCanReceiveMarkupExtension(MarkupExtension markupExtension, IProvideValueTarget provideValueTarget, DependencyObject& targetDependencyObject, DependencyProperty& targetDependencyProperty)
       at System.Windows.Data.BindingBase.ProvideValue(IServiceProvider serviceProvider)
       at System.Windows.Markup.BamlRecordReader.ProvideValueFromMarkupExtension(MarkupExtension markupExtension, Object obj, Object member)
       at System.Windows.Markup.BamlRecordReader.SetClrComplexPropertyCore(Object parentObject, Object value, MemberInfo memberInfo)
       at System.Windows.Markup.BamlRecordReader.SetClrComplexProperty(Object parentObject, MemberInfo memberInfo, Object o)
       at System.Windows.Markup.BamlRecordReader.SetPropertyValueToParent(Boolean fromStartTag, Boolean& isMarkupExtension)
       at System.Windows.Markup.BamlRecordReader.ReadElementEndRecord(Boolean fromNestedBamlRecordReader)
       at System.Windows.Markup.BamlRecordReader.ReadRecord(BamlRecord bamlRecord)
       at System.Windows.Markup.BamlRecordReader.Read(Boolean singleRecord)
       at System.Windows.Markup.TreeBuilderBamlTranslator.ParseFragment()
       at System.Windows.Markup.TreeBuilder.Parse()
       at System.Windows.Markup.XamlReader.LoadBaml(Stream stream, ParserContext parserContext, Object parent, Boolean closeStream)
       at System.Windows.Application.LoadComponent(Object component, Uri resourceLocator)
       at CakeBoss.WPF.RecipeListView.InitializeComponent() in c:\Dev\CakeBoss2009\trunk\code\CakeBoss.WPF\RecipeList\RecipeListView.xaml:line 1
       at CakeBoss.WPF.RecipeListView..ctor() in C:\Dev\CakeBoss2009\trunk\code\CakeBoss.WPF\RecipeList\RecipeListView.xaml.cs:line 13
  InnerException:

19 Answers, 1 is accepted

Sort by
0
Hristo
Telerik team
answered on 09 Jun 2009, 09:13 AM
Hello Jon Masters,

Unfortunately Command property is not DependencyProperty so you cannot bind it.
But there is a workaround - you can use attach binding. Here is a simple class with one attached property that can be bound and when value changed sets the Command of MouseBinding.

Here is the Helper class:
public class AttachedMouseBinding  
{  
    public static ICommand GetCommand(DependencyObject obj)  
    {  
        return (ICommand)obj.GetValue(CommandProperty);  
    }  
 
    public static void SetCommand(DependencyObject obj, ICommand value)  
    {  
        obj.SetValue(CommandProperty, value);  
    }  
 
    public static readonly DependencyProperty CommandProperty =  
        DependencyProperty.RegisterAttached("Command"typeof(ICommand), typeof(AttachedMouseBinding),  
        new FrameworkPropertyMetadata(CommandChanged));  
 
    private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
    {  
        InputBinding inputBinding = d as InputBinding;  
        ICommand command = e.NewValue as ICommand;  
        if (inputBinding != null)  
        {  
            inputBinding.Command = command;  
        }  
    }  

and you can use it like this:
<telerik:RadGridView ItemsSource="{Binding Items}">  
    <telerik:RadGridView.InputBindings> 
        <MouseBinding Gesture="RightClick"   
                      local:AttachedMouseBinding.Command="{Binding Source={x:Static ApplicationCommands.Close}}" />               
    </telerik:RadGridView.InputBindings> 
</telerik:RadGridView> 

You can further extend the AttachMouseBinding class and add CommandParameter or CommandTarget properties if you need them.

I hope this helps.

Regards,
Hristo
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Stanley
Top achievements
Rank 1
answered on 14 Jun 2009, 09:01 PM
I tried the attached property workaround and it is not working for me.  Does the actual ICommand itself have to be static also?  The command I am trying to use works for me when a button is bound to it.   However trying to use the attached property does not work.

<Grid> 
            <telerik:RadGridView IsFilteringAllowed="True" AutoGenerateColumns="False" ColumnsWidthMode="Fill" 
             ShowGroupPanel="False"   IsReadOnly="True"   DataLoadMode="Asynchronous"  ItemsSource="{Binding Path=Items }" SelectedItem="{Binding Path=SelectedItem}"   
                       > 
 
                <telerik:RadGridView.Columns> 
                    <telerik:GridViewDataColumn UniqueName="LastName" HeaderText="Last Name"  /> 
                    <telerik:GridViewDataColumn UniqueName="FirstName" HeaderText="First Name" /> 
                    <telerik:GridViewDataColumn UniqueName="PersonnelNumber" HeaderText="Personnel Number" /> 
                    <telerik:GridViewDataColumn UniqueName="Initials" HeaderText="Initials"/>  
                    <telerik:GridViewDataColumn UniqueName="IsActive" HeaderText="Active?"/>  
                </telerik:RadGridView.Columns> 
                  
                <telerik:RadGridView.InputBindings > 
                    <MouseBinding Gesture="LeftDoubleClick"     
                      vm:AttachedMouseBinding.Command="{Binding Path=Edit}"   /> 
                </telerik:RadGridView.InputBindings> 
 
 
 
            </telerik:RadGridView> 
        </Grid> 
using System;  
using System.Collections.Generic;  
using System.Linq;  
using System.Text;  
using System.Windows.Input;  
using System.ComponentModel;  
using System.Windows;  
 
namespace CardinalHealth.SYNtrac.ViewModel  
{  
    public class AttachedMouseBinding  
    {  
        public static ICommand GetCommand(DependencyObject obj)  
        {  
            return (ICommand)obj.GetValue(CommandProperty);  
        }  
 
        public static void SetCommand(DependencyObject obj, ICommand value)  
        {  
            obj.SetValue(CommandProperty, value);  
        }  
 
        public static readonly DependencyProperty CommandProperty =  
            DependencyProperty.RegisterAttached("Command", typeof(ICommand), typeof(AttachedMouseBinding),  
            new FrameworkPropertyMetadata(CommandChanged));  
 
        private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
        {  
            InputBinding inputBinding = d as InputBinding;  
            ICommand command = e.NewValue as ICommand;  
            if (inputBinding != null)  
            {  
                inputBinding.Command = command;  
            }  
        }  
    }    
 
}  
 
0
Hristo
Telerik team
answered on 15 Jun 2009, 11:46 AM
Hi Stanley,

If you want to bind to instance commands (not static) then you can use other techniques.
The first one (and most used) is to expose InputBindings from your view model and set this input binding in the view.
The second - you can modify AttachedMouseBinding to create new InputBinding and attach it to the radGridView.
Here is example of both implementation. (The one with exposed InputBindings is commented in SetViewModel method).

<Window x:Class="WpfApplication1.Window1" 
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" Name="RootWindow" 
        xmlns:local="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300">  
    <Window.CommandBindings> 
        <CommandBinding Command="ApplicationCommands.Close" Executed="CommandBinding_Executed" /> 
    </Window.CommandBindings> 
    <Grid> 
        <telerik:RadGridView ItemsSource="{Binding Items}" x:Name="GridView" 
                             local:AttachedMouseBinding.Command="{Binding ExitCommand}">  
        </telerik:RadGridView> 
    </Grid> 
</Window> 

code-behind:
using System.Windows;  
using System.Windows.Input;  
 
namespace WpfApplication1  
{  
    /// <summary>  
    /// Interaction logic for Window1.xaml  
    /// </summary>  
    public partial class Window1 : Window  
    {  
        public Window1()  
        {  
            InitializeComponent();  
 
            GridViewViewModel viewModel = new GridViewViewModel();  
            SetViewModel(viewModel);  
 
        }  
 
        private void SetViewModel(GridViewViewModel viewModel)  
        {  
            this.DataContext = viewModel;  
            //this.GridView.InputBindings.AddRange(viewModel.InputBindings);  
        }  
 
 
        private void CommandBinding_Executed(object sender, ExecutedRoutedEventArgs e)  
        {  
            this.Close();  
        }  
    }     

and the modified AttachedMouseBinding.cs
using System.Windows;  
using System.Windows.Input;  
 
namespace WpfApplication1  
{  
    public class AttachedMouseBinding  
    {  
        public static ICommand GetCommand(DependencyObject obj)  
        {  
            return (ICommand)obj.GetValue(CommandProperty);  
        }  
 
        public static void SetCommand(DependencyObject obj, ICommand value)  
        {  
            obj.SetValue(CommandProperty, value);  
        }  
 
        public static readonly DependencyProperty CommandProperty =  
            DependencyProperty.RegisterAttached("Command"typeof(ICommand), typeof(AttachedMouseBinding),  
            new FrameworkPropertyMetadata(CommandChanged));  
 
        private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
        {  
            FrameworkElement fe = d as FrameworkElement;  
            ICommand command = e.NewValue as ICommand;  
 
            InputBinding inputBinding = new InputBinding(command, new MouseGesture(MouseAction.RightClick));  
            fe.InputBindings.Add(inputBinding);  
        }  
 
    }  

Please note that for brevity I have hard coded the gesture but you can expose another property for it.

I hope this clarifies the possible solutions.


Regards,
Hristo
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Stanley
Top achievements
Rank 1
answered on 15 Jun 2009, 02:10 PM
Where is ExitCommand defined in your example.  Is this just a typo?  Is it possible to put the Commandbindings ina resource dictionary.

Thanks,  This will probably work for me.

<Window x:Class="WpfApplication1.Window1"    
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"    
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"    
        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation" Name="RootWindow"    
        xmlns:local="clr-namespace:WpfApplication1" Title="Window1" Height="300" Width="300">     
    <Window.CommandBindings>    
        <CommandBinding Command="ApplicationCommands.Close" Executed="CommandBinding_Executed" />    
    </Window.CommandBindings>    
    <Grid>    
        <telerik:RadGridView ItemsSource="{Binding Items}" x:Name="GridView"    
                             local:AttachedMouseBinding.Command="{Binding ExitCommand}">     
        </telerik:RadGridView>    
    </Grid>    
</Window>    
 
0
Hristo
Telerik team
answered on 16 Jun 2009, 08:01 AM
Hello Stanley,

The ExitCommand is defined in the ViewModel but the code viewer stripped it somehow.
I'm attaching the project as a zip file.
As for the CommandBinding you cannot define it in resources. You have to do it in xaml or code. I've add it to Window because I want window to handle ExitCommand.

Let me know if this works for you.

All the best,
Hristo
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Stanley
Top achievements
Rank 1
answered on 19 Jun 2009, 08:48 PM
I have played around with your example and have discovered that this type of binding works for most Gestures/MouseActions but does not work for the DoubleLeftClick action.  Using your example if I replace the RightClick with DoubleLeftClick, no actions happens.  So as it stands right now this does not appear to work for DoublLeftClick.

Are there any other options for the LeftDoubleClick.  It appears on the surface that maybe the grid is internally capturing the LeftDoubleClick for another event or pre-event.
0
Hristo
Telerik team
answered on 23 Jun 2009, 03:18 PM
Hello Stanley,

I was able to change the RightClick gesture to LeftDoubleClick and everything works.
I've modified the sample (using the approach with AttachedBindings) - just don't forget to change it in the code behind:
private static void CommandChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)  
{  
    FrameworkElement fe = d as FrameworkElement;  
    ICommand command = e.NewValue as ICommand;  
 
    InputBinding inputBinding = new InputBinding(command, new MouseGesture(MouseAction.LeftDoubleClick));  
    fe.InputBindings.Add(inputBinding);  

I hope this help.

Greetings,
Hristo
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Stanley
Top achievements
Rank 1
answered on 23 Jun 2009, 04:01 PM
The LeftDoubleClick works when you do it within the window.  However when you LeftDoubleClick on an item in the RadGrid it does not respond.  Our requirement is to have the user LeftDoubleClick on a GridRowItem.
0
Hristo
Telerik team
answered on 24 Jun 2009, 03:45 PM
Hi Stanley,

You are right - LeftDoubleClick is not working when you click over GridViewRow (we were handling mouseLeftButtonDown event).
This issue is already fixed it and it will be available with our next Q2 official release.

Thanks for your patience and understanding.

Best wishes,
Hristo
the Telerik team

Instantly find answers to your questions on the new Telerik Support Portal.
Check out the tips for optimizing your support resource searches.
0
Eli Perp
Top achievements
Rank 1
answered on 12 Apr 2010, 01:15 PM
Hi,

I have tried this with version 2010.1.309.35, Still no luck with the left double click.
Is this fixed now? or is there another way to bind the double click to a ViewModels command?

Regards,
Eli
0
Tsvyatko
Telerik team
answered on 12 Apr 2010, 01:35 PM
Hello Eli Perp,

Please check the attached project. It demonstrates how one can use the events introduced in the control and transmute them to commands.

Let me know if this works for you.

All the best,
Tsvyatko
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Eli Perp
Top achievements
Rank 1
answered on 12 Apr 2010, 03:30 PM
Thanks Tsvyatko,

That worked well. Just a few questions:

1) I assume this will work with all events that need to be transmuted into a command, not just Telerik controls?
2) Is it possible to limit the scope of the double click to the actual list? When i double click on the header or the column names it still fires the double click event.
3) I do not understand the radgridview with the behavuours attached? What is this used for?

Thanks,
Eli

0
Tsvyatko
Telerik team
answered on 14 Apr 2010, 09:25 AM
Hi Eli Perp,

1) Yes, the idea used in the sample is not limited to telerik controls and  can be used for any WPF control.

2)  You can limit the scope of double click event invocation by using PreviewMouseDoubleClick and set the current Item to null. Then when the Command begins to execute is will check CanExecute Method which will cancel its execution.

3) The idea of the behavior from the last example is to move the logic related to the event outside the view and keeping its code behind clean, while in the same time encapsulating common logic, making it reusable.

If you have any other questions or issues do not hesitate to contact us.

Greetings,
Tsvyatko
the Telerik team

Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items.
0
Steve Evans
Top achievements
Rank 1
answered on 21 Jun 2010, 11:03 AM
Hi There,

I am looking to assign some keyboard gestures to the RadGridView and would like to know if it s still the case that I would have to use the approach recommended in this thread? 

I was assuming that I could do something like the following:

<Controls:RadGridView.InputBindings>
     <KeyBinding Key="ADD" Command="{Binding IncrementPriceCommand}" />
     <KeyBinding Key="SUBTRACT" Command="{Binding DecrementPriceCommand}" />
</Controls:RadGridView.InputBindings>

Is this not the case?

Thanks in advance, Steve
0
Tsvyatko
Telerik team
answered on 21 Jun 2010, 03:30 PM
Hello Steve Evans,

Unfortunately, since InputBindings does not have SetBinding method (since the are dependency objects) you cannot set binding to it properties.

 In this case you can use one of the following options:

 - Inherit DefaultKeyboardProvider of the GridView with custom implementation  - calling commands, etc. in it. (and link it to the GridView using KeyboardCommandProvider property)

- Create behavior (by inheriting) that called the commands.

- Use InputBindings and provide static commands directly.

Please, let me know if you need any further assistance or sample of the option you prefer and fits best in your case.

Greetings,
Tsvyatko
the Telerik team
Do you want to have your say when we set our development plans? Do you want to know when a feature you care about is added or when a bug fixed? Explore the Telerik Public Issue Tracking system and vote to affect the priority of the items
0
Eli Perp
Top achievements
Rank 1
answered on 21 Jun 2010, 05:14 PM
Hi Steve,

WPF 4 supports dependancy property binding to inputbinding
http://msdn.microsoft.com/en-us/library/bb613588.aspx#binding

upgrade to .net 4.0 and you will be able to do this.

Kind Regards,
Eli Perpinyal
0
Steve Evans
Top achievements
Rank 1
answered on 22 Jun 2010, 08:53 AM
Hi Guys,

Thanks for the info. 

I am actually using .Net 4 and as per Eli's message it does actually work as I had thought that it should...I was actually just not pressing the right keys when trying to test my key bindings had been set up correctly....doh!.

Thanks agin.

Steve
0
Ramesh
Top achievements
Rank 1
answered on 28 Aug 2012, 11:55 AM
//
WPF 4 supports dependancy property binding to inputbinding 
http://msdn.microsoft.com/en-us/library/bb613588.aspx#binding

upgrade to .net 4.0 and you will be able to do this.
//

Hi Eli,

I'm actually using .net 4.0. But, still not working as you said. 

Here is the xaml code

<telerik:RadGridView  Grid.Row="1"
                                              CanUserFreezeColumns="False"
                                              CanUserInsertRows="False"
                                              IsReadOnly="True"
                                              AutoGenerateColumns="False"
                                              ItemsSource="{Binding}"
                                              SelectedItem="{Binding Path=SelectedItem, Mode=TwoWay}"
                                              CanUserReorderColumns="False"
                                              EnableRowVirtualization="True"
                                              ShowColumnHeaders="True"
                                              CanUserSelect="True"
                                              
                                              ShowGroupPanel="False"
                                              MinHeight="400"
                                              CanUserDeleteRows="False"
                                              RowIndicatorVisibility="Collapsed"
                                              x:Name="grid"
                                              >
 
                            <telerik:RadGridView.InputBindings>
                                <MouseBinding MouseAction="LeftDoubleClick" x:Name="mouseBinding"
                                              Command="{Binding EditCommand.Command, Mode=OneTime}" />
                            </telerik:RadGridView.InputBindings>
 
                            <telerik:RadGridView.Columns>
                                <telerik:GridViewDataColumn Header="Description"
                                                            DataMemberBinding="{Binding Path=Entity.Description}"
                                                            Width="250*" />
                                <telerik:GridViewDataColumn Header="External Description"
                                                            DataMemberBinding="{Binding Path=Entity.ExternalDescription}"
                                                            Width="250*" />
                                <telerik:GridViewDataColumn Header="Archive"
                                                            DataMemberBinding="{Binding Path=Entity.Archive}"
                                                            Width="60*" />
                            </telerik:RadGridView.Columns>
                        </telerik:RadGridView>
No errors in the output Window as well. 

Please help.
Thanks in advance for your help

Ramesh R
0
paul
Top achievements
Rank 1
answered on 03 Sep 2019, 09:24 AM

[quote]Eli Perp said:Hi Steve,

WPF 4 supports dependancy property binding to inputbinding
http://msdn.microsoft.com/en-us/library/bb613588.aspx#essay writer
upgrade to .net 4.0 and you will be able to do this.

Kind Regards,
Eli Perpinyal
[/quote]

Note that only dependency property can be data bound.

 

Tags
GridView
Asked by
Jon
Top achievements
Rank 1
Answers by
Hristo
Telerik team
Stanley
Top achievements
Rank 1
Eli Perp
Top achievements
Rank 1
Tsvyatko
Telerik team
Steve Evans
Top achievements
Rank 1
Ramesh
Top achievements
Rank 1
paul
Top achievements
Rank 1
Share this question
or