Hi,
I've a hierarchical XamDataGrid and would like that when the user double-clicks on a row that's not a root I take some action. Ideally I'd like to attach a blend Interaction.Triggers with an EventTrigger that calls a InvokeCommandAction which will invoke a command on my ViewModel, but if there's a way to directly invoke a command on mouse-double-click that's also fine :)
Again, I don't want to register on the whole grid's double-click, but only for child records (or particular field layouts).
Any ideas how I can do this?
Thanks!
Here it is, the control template for the CellValuePresenter plus the style for attaching it to the grid:
<ControlTemplate TargetType="igDP:CellValuePresenter" x:Key="GridCellValuePresenterTemplate" > <igWindows:CardPanel> <Border BorderThickness="{TemplateBinding Border.BorderThickness}" CornerRadius="{TemplateBinding igDP:CellValuePresenter.CornerRadius}" BorderBrush="{TemplateBinding Border.BorderBrush}" Background="{TemplateBinding Panel.Background}" Name="MainBorder" /> <Rectangle Fill="{TemplateBinding igDP:CellValuePresenter.BackgroundActive}" Stroke="{TemplateBinding igDP:CellValuePresenter.BorderActiveBrush}" StrokeThickness="1" Name="Active" Width="Auto" Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Opacity="1" Visibility="Collapsed" SnapsToDevicePixels="True" /> <ContentControl> <ContentPresenter Content="{TemplateBinding ContentControl.Content}" ContentTemplate="{TemplateBinding ContentControl.ContentTemplate}" ContentStringFormat="{TemplateBinding ContentControl.ContentStringFormat}" Style="{TemplateBinding igDP:CellValuePresenter.ForegroundStyle}" Name="PART_EditorSite" Margin="{TemplateBinding Control.Padding}" HorizontalAlignment="{TemplateBinding Control.HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding Control.VerticalContentAlignment}" /> <i:Interaction.Triggers> <i:EventTrigger EventName="MouseDoubleClick"> <n:ExecuteCommandAction Command="{StaticResource ShowDetailsCommandRelay}" Parameter="{Binding DataItem}"/> </i:EventTrigger> </i:Interaction.Triggers> </ContentControl> </igWindows:CardPanel> <ControlTemplate.Triggers> <Trigger Property="igDP:CellValuePresenter.IsMouseOverRecord"> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="igDP:CellValuePresenter.IsRecordSelected"> <Setter Property="Border.BorderThickness"> <Setter.Value> <Thickness>0,0,1,0</Thickness> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Margin"> <Setter.Value> <Thickness>0,0,-1,0</Thickness> </Setter.Value> </Setter> <Setter Property="Control.Padding"> <Setter.Value> <Thickness>2,0,3,0</Thickness> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="igDP:DataItemPresenter.HighlightAsPrimary"> <Setter Property="Panel.Background"> <Setter.Value> <Binding Path="BackgroundPrimary" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush"> <Setter.Value> <Binding Path="BorderPrimaryBrush" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Style" TargetName="PART_EditorSite"> <Setter.Value> <Binding Path="ForegroundPrimaryStyle" RelativeSource="{RelativeSource Mode=TemplatedParent}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="igDP:CellValuePresenter.IsFieldSelected"> <Setter Property="Panel.Background"> <Setter.Value> <Binding Path="BackgroundFieldSelected" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush"> <Setter.Value> <Binding Path="BorderFieldSelectedBrush" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Style" TargetName="PART_EditorSite"> <Setter.Value> <Binding Path="ForegroundFieldSelectedStyle" RelativeSource="{RelativeSource Mode=TemplatedParent}" /> </Setter.Value> </Setter> <Setter Property="igDP:CellValuePresenter.CornerRadius"> <Setter.Value> <CornerRadius>4,4,4,4</CornerRadius> </Setter.Value> </Setter> <Setter Property="Border.BorderThickness"> <Setter.Value> <Thickness>1,1,1,1</Thickness> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="igDP:CellValuePresenter.IsSelected"> <Setter Property="Panel.Background"> <Setter.Value> <Binding Path="BackgroundSelected" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush"> <Setter.Value> <Binding Path="BorderSelectedBrush" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Style" TargetName="PART_EditorSite"> <Setter.Value> <Binding Path="ForegroundSelectedStyle" RelativeSource="{RelativeSource Mode=TemplatedParent}" /> </Setter.Value> </Setter> <Setter Property="igDP:CellValuePresenter.CornerRadius"> <Setter.Value> <CornerRadius>4,4,4,4</CornerRadius> </Setter.Value> </Setter> <Setter Property="Border.BorderThickness"> <Setter.Value> <Thickness>1,1,1,1</Thickness> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <Trigger Property="igDP:CellValuePresenter.IsActive"> <Setter Property="FrameworkElement.Style" TargetName="PART_EditorSite"> <Setter.Value> <Binding Path="ForegroundActiveStyle" RelativeSource="{RelativeSource Mode=TemplatedParent}" /> </Setter.Value> </Setter> <Setter Property="UIElement.Visibility" TargetName="Active"> <Setter.Value> <x:Static Member="Visibility.Visible" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="UIElement.IsMouseOver"> <Condition.Value> <s:Boolean>True</s:Boolean> </Condition.Value> </Condition> <Condition Property="igDP:CellValuePresenter.IsSelected"> <Condition.Value> <s:Boolean>False</s:Boolean> </Condition.Value> </Condition> <Condition Property="igDP:CellValuePresenter.IsFieldSelected"> <Condition.Value> <s:Boolean>False</s:Boolean> </Condition.Value> </Condition> </MultiTrigger.Conditions> <Setter Property="Panel.Background"> <Setter.Value> <Binding Path="BackgroundHover" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush"> <Setter.Value> <Binding Path="BorderHoverBrush" RelativeSource="{RelativeSource Mode=Self}" /> </Setter.Value> </Setter> <Setter Property="FrameworkElement.Style" TargetName="PART_EditorSite"> <Setter.Value> <Binding Path="ForegroundHoverStyle" RelativeSource="{RelativeSource Mode=TemplatedParent}" /> </Setter.Value> </Setter> </MultiTrigger> <DataTrigger Binding="{Binding Path=Field.IsFixedStateChanging, RelativeSource={RelativeSource Mode=Self}}" Value="True"> <Setter Property="Panel.Background"> <Setter.Value> <SolidColorBrush>#AA8DBAEB</SolidColorBrush> </Setter.Value> </Setter> <Setter Property="Border.BorderBrush"> <Setter.Value> <SolidColorBrush>#AA8DBAEB</SolidColorBrush> </Setter.Value> </Setter> </DataTrigger> <Trigger Property="igDP:CellValuePresenter.IsDataErrorTemplateActive"> <Setter Property="ContentControl.ContentTemplate" TargetName="PART_EditorSite"> <Setter.Value> <DynamicResource ResourceKey="{x:Static igDP:DataPresenterBase.DataErrorContentTemplateKey}" /> </Setter.Value> </Setter> <Trigger.Value> <s:Boolean>True</s:Boolean> </Trigger.Value> </Trigger> </ControlTemplate.Triggers> </ControlTemplate>Then in the grid do: <igDP:XamDataGrid.Resources> <Style TargetType="{x:Type igDP:CellValuePresenter}" x:Key="Blah"> <Setter Property="Template" Value="{StaticResource GridCellValuePresenterTemplate}"/> </Style> </igDP:XamDataGrid.Resources> <igDP:FieldLayout> <igDP:FieldLayout.FieldSettings> <igDP:FieldSettings CellClickAction="SelectRecord" CellValuePresenterStyle="{StaticResource Blah}" /> </igDP:FieldLayout.FieldSettings></igDP:FieldLayout>
<igDP:XamDataGrid.Resources> <Style TargetType="{x:Type igDP:CellValuePresenter}" x:Key="Blah"> <Setter Property="Template" Value="{StaticResource GridCellValuePresenterTemplate}"/> </Style> </igDP:XamDataGrid.Resources>
<igDP:FieldLayout> <igDP:FieldLayout.FieldSettings> <igDP:FieldSettings CellClickAction="SelectRecord" CellValuePresenterStyle="{StaticResource Blah}" /> </igDP:FieldLayout.FieldSettings></igDP:FieldLayout>
Adrian, Please could you share your code with me for getting this feature. I'm trying to implement the same functionality.
Thanks,
Shravan
Thanks for the answer Vlad, I grouped the ContentPresenter in the CellValuePresenter in a ContentControl and attached my behavior to it, with parameter {Binding DataItem}. It works :)
The resolution that Alex suggested is about creating a style for the CellValuePresenter or the DataRecordCellArea and attach the MouseDoubleClick event of a visual element in the template to a command in your viewmodel. You can pass the datacontext as a commandparameter in that case.
Another option is to use the MouseDoubleClick event of the grid and pass the ActiveDataItem as parameter or even the MouseEventArgs using PassEventArgsToCommand="True" in the EventToCommand definition. Note that this event will fire for each element in the grid but you can check the type in the CanExecute method and suppress the execution.
We would appreciate if you give us your feedback on this new feature request here and we will try to include it in future releases.
Hi Alex,
I believe you are referring to attaching a code-behind event handler, right? While this would work, I'd ideally like to be able to attach a behavior that calls a command in the viewmodel, or somehow call a command directly.
My current solution is to attach a behavior like ExecuteTypeFilteredCommandAction, which subscribes to the MouseDoubleClick event of the grid and looks if the ActiveItem is of a certain type, so that the command only gets executed for nested records. This works but it's a bit suboptimal :)
Maybe there's a better way?
Thanks