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

EventToTrigger - Extracting Item to Send as Parameter

11 Answers 141 Views
GridView
This is a migrated thread and some comments may be shown as answers.
David
Top achievements
Rank 1
David asked on 04 Feb 2012, 03:33 AM
I have a screen which has a Gridview and 2 heirarchies within it.

At the moment, I am using the RowEditEnded event of the GridView (and its embedded Grids) to perform updates. I am doing it in such a way which is not very MVVM. For example:
private void TasksRadGridView_RowEditEnded(object sender, Telerik.Windows.Controls.GridViewRowEditEndedEventArgs e)
{
    Task updatedTask = e.NewData as Task;
    ManageProjectsViewModel vm = this.DataContext as ManageProjectsViewModel;
    vm.UpdateTaskCommand.Execute(updatedTask);
}

You can see there that I am casting the DataContext as a ViewModel.
I would prefer to bind directly to properties on the ViewModel in Xaml.

The current Xaml for that UserControl is:
<UserControl x:Class="TimeTracker.View.ManageProjectsView.ManageProjectsView"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
             xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
             xmlns:cmd="clr-namespace:GalaSoft.MvvmLight.Command;assembly=GalaSoft.MvvmLight.Extras.WPF4"
             mc:Ignorable="d"
             d:DesignHeight="300" d:DesignWidth="300"
             DataContext="{Binding ManageProjects, Source={StaticResource Locator}}">
     
    <UserControl.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="../../Skins/MainSkin.xaml" />
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </UserControl.Resources>
 
    <Grid>
        <!-- This Border is just a container to provide the transparent effect as a layer above the clock-->
        <Border Grid.Row="1" Height="Auto" Width="Auto">
            <Grid Height="Auto" Width="Auto" Background="#990D0529">
                <Border Padding="10" Margin="0" Width="630" Height="600" CornerRadius="10" BorderBrush="#FF3F3636"
                BorderThickness="1" Background="{StaticResource TransparentBrush}">
                    <Border Padding="10" Height="450" Width="580" CornerRadius="10" BorderBrush="#FF3F3636" BorderThickness="1" Background="{StaticResource TransparentBrush}">
                        <Grid Height="Auto" Width="Auto" Background="#990D0529">
 
                            <telerik:RadGridView x:Name="ProjectsRadGridView" AutoGenerateColumns="False"
                                                 ColumnWidth="*" GridLinesVisibility="None" telerik:StyleManager.Theme="Transparent"
                                                 RowIndicatorVisibility="Collapsed" IsReadOnly="False"
                                                 ItemsSource="{Binding Path=Projects}"
                                                 RowEditEnded="ProjectsRadGridView_RowEditEnded">
 
                                <telerik:RadGridView.ChildTableDefinitions>
                                    <telerik:GridViewTableDefinition />
                                </telerik:RadGridView.ChildTableDefinitions>
 
                                <telerik:RadGridView.Columns>
                                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Id}" Header="Project Id" UniqueName="Id" IsVisible="False" />
                                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ProjectName}" Header="Name" UniqueName="ProjectName" IsReadOnly="False"/>
                                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Visible}" Header="Visible" UniqueName="Visible" IsReadOnly="False" />
                                </telerik:RadGridView.Columns>
 
                                <telerik:RadGridView.HierarchyChildTemplate>
                                    <DataTemplate>
                                        <telerik:RadGridView x:Name="TasksRadGridView" BorderThickness="0,1,0,1"
                                                             telerik:StyleManager.Theme="Transparent"
                                                             RowEditEnded="TasksRadGridView_RowEditEnded"
                                                             GridLinesVisibility="None" CanUserFreezeColumns="False"
                                                             AutoGenerateColumns="False" ItemsSource="{Binding Tasks}" 
                                                             ShowGroupPanel="False" IsReadOnly="False">
                                                 
                                            <telerik:RadGridView.ChildTableDefinitions>
                                                <telerik:GridViewTableDefinition />
                                            </telerik:RadGridView.ChildTableDefinitions>
 
                                            <telerik:RadGridView.Columns>
                                                <telerik:GridViewDataColumn DataMemberBinding="{Binding Id}" Header="Task ID" IsVisible="False" />
                                                <telerik:GridViewDataColumn DataMemberBinding="{Binding TaskName, UpdateSourceTrigger=PropertyChanged}" Header="Name" />
                                                <telerik:GridViewDataColumn DataMemberBinding="{Binding Description}" Header="Description" />
                                                <telerik:GridViewDataColumn DataMemberBinding="{Binding Visible}" Header="Visible" />
                                            </telerik:RadGridView.Columns>
 
                                            <telerik:RadGridView.HierarchyChildTemplate>
                                                <DataTemplate>
                                                    <telerik:RadGridView x:Name="WorkItemsRadGridView" BorderThickness="0,1,0,1"
                                                             telerik:StyleManager.Theme="Transparent"
                                                             RowEditEnded="WorkItemsRadGridView_RowEditEnded"
                                                             GridLinesVisibility="None" CanUserFreezeColumns="False"
                                                             AutoGenerateColumns="False" ItemsSource="{Binding WorkItems}" 
                                                             ShowGroupPanel="False" IsReadOnly="False">
                                                        <telerik:RadGridView.Columns>
                                                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Id}" Header="Work Item ID" IsVisible="False" />
                                                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Duration}" Header="Duration" IsReadOnly="False" />
                                                            <telerik:GridViewDataColumn DataMemberBinding="{Binding Description}" Header="Description" IsReadOnly="False" />
                                                            <telerik:GridViewDataColumn DataMemberBinding="{Binding DateOfWork}" Header="DateOfWork" IsReadOnly="False" />
                                                        </telerik:RadGridView.Columns>
                                                    </telerik:RadGridView>
                                                </DataTemplate>
                                            </telerik:RadGridView.HierarchyChildTemplate>
 
                                        </telerik:RadGridView>
                                    </DataTemplate>
                                </telerik:RadGridView.HierarchyChildTemplate>
                            </telerik:RadGridView>
 
                        </Grid>
                    </Border>
                </Border>
            </Grid>
        </Border>
    </Grid>
 
</UserControl>


I think one part of the problem is that the embedded Grids are not binding to separate ViewModels. They are binding to the relevant property on the ViewModel:
e.g. the 1st embedded GridView is TasksRadGridView. It binds as so:
ItemsSource="{Binding Path=Projects}"
    

Is there a way to directly binding to the ViewModel, passing it the valie of the current ro being edited for the embedded grids?
I am familiar with the EventToCommand trigger of the MVVM Light Toolkit. I just can't find a way to extract the value for the current row being edited for items in the embedded Grids. The item would be sent as a parameter using the EventToCommand trigger (I think that is the best design).

Cheers

Cheers

11 Answers, 1 is accepted

Sort by
0
David
Top achievements
Rank 1
answered on 16 Feb 2012, 01:33 PM
Bump
0
Vlad
Telerik team
answered on 20 Feb 2012, 02:46 PM
Hello,

 In my opinion you should not use any grid events if you want to have pure MVVM. If you use for example IEditableObject for your data items the grid will work with this interface and you can perform updates directly from your model. 

Greetings,
Vlad
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
David
Top achievements
Rank 1
answered on 20 Feb 2012, 11:16 PM
Is there an example of that in any of the demos?
0
Vlad
Telerik team
answered on 21 Feb 2012, 08:06 AM
Hello,

 You can check the example on the official MSDN article.

All the best,
Vlad
the Telerik team
Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
0
David
Top achievements
Rank 1
answered on 21 Feb 2012, 10:45 PM
Unfortunately, that is not going to solve the problem I am having at the presentation level.

I need to know how to bind the selected item in a heirarchic grid (not the top level grid) to a property of the ViewModel, whereby there is no specific ViewModel for the embedded grids, which use the top level ViewModel.
0
Rayne
Top achievements
Rank 1
answered on 23 Feb 2012, 04:35 PM
Can you try naming the control and the grid then using an ElementName binding for the event command (the path would be DataContext.ViewModelProperty of the UserControl)? Then bind the command parameter to the SelectedItem of the child grid (again using ElementName). If that doesn't work, try using a RelativeSource binding and going up one ancestor level to get the child grid.

Binding inside a DataTemplate is tricky and I've struggled with it for days trying to find the best way to bind my viewmodel properties and methods. 
0
David
Top achievements
Rank 1
answered on 27 Feb 2012, 10:13 AM
Hi Rayne,

Thanks for the suggestion. I named the inner grids and I've been trying several binding combinations, including the following:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="SelectedCellsChanged" SourceName="TasksRadGridView">
        <cmd:EventToCommand Command="{Binding Path=UpdateTaskCommand, Mode=TwoWay}"
                            CommandParameter="{Binding ElementName=TasksRadGridView, Path=SelectedItem }" />
    </i:EventTrigger>
</i:Interaction.Triggers>

None of them seem to catch the event. Not sure what else to try.
0
Rayne
Top achievements
Rank 1
answered on 27 Feb 2012, 02:58 PM
You are using a Static Resource as the DataContext for the UserControl. Could you use that same resource for the those pesky bindings? Your DataContext is binding to ManageProjects so your events would bind to Path=ManageProjects.UpdateTaskCommand? Would that work?
0
David
Top achievements
Rank 1
answered on 28 Feb 2012, 09:35 AM
Thanks for the suggestion. Alas, it did not get me there.

I must say, I am a little underwhelmed by the Telerik interest in this thread. To me, it is telling in their enthusiasm for people getting skilled in their controls.
0
David
Top achievements
Rank 1
answered on 08 Mar 2012, 10:06 AM
I am awesome:

<i:Interaction.Triggers>
    <i:EventTrigger EventName="RowEditEnded">
        <cmd:EventToCommand Command="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}, Path=DataContext.UpdateTaskCommand}"
                            PassEventArgsToCommand="True"/>
    </i:EventTrigger>
</i:Interaction.Triggers>
0
Rayne
Top achievements
Rank 1
answered on 08 Mar 2012, 02:46 PM
I'm glad you finally figured it out! Databinding can be so tricky sometimes.
Tags
GridView
Asked by
David
Top achievements
Rank 1
Answers by
David
Top achievements
Rank 1
Vlad
Telerik team
Rayne
Top achievements
Rank 1
Share this question
or