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

[Solved] RowEditEnded Not Firing

6 Answers 223 Views
GridView
This is a migrated thread and some comments may be shown as answers.
This question is locked. New answers and comments are not allowed.
Scott
Top achievements
Rank 2
Scott asked on 10 Nov 2010, 11:18 PM
First of all, thanks for such a great grid.  So far I've been very impressed.  One thing isn't working quite right, however, and I hope you guys can point me in the right direction.  Currently, I have a RadGridView within a user control.  I'm using Prism/MVVM, and I've hooked up a custom command for RowEditEnded.

What I've noticed is that if I press the <Enter> key to skip down to the next row, then the RowEditEnded command fires properly, and everything works as I expect.  However if I manually click on another row in the grid, the RowEditEnded command does not fire at all.  Here's the XAML for my User Control:

<UserControl x:Class="ARI.Shopping.MassUpdater.DetailsBox.DetailsBoxView"
    xmlns:commands="clr-namespace:ARI.Shopping.MassUpdater.Infrastructure.Commands;assembly=ARI.Shopping.MassUpdater.Infrastructure"
    xmlns:helpers="clr-namespace:ARI.Shopping.MassUpdater.Infrastructure.Helpers;assembly=ARI.Shopping.MassUpdater.Infrastructure"
    mc:Ignorable="d" d:DesignHeight="300" d:DesignWidth="900">
      
    <UserControl.Resources>
        <Style TargetType="telerik:GridViewRow" x:Key="RowBackgroundToggle">
            <Setter Property="helpers:SetterValueBinding.PropertyBinding">
                <Setter.Value>
                    <helpers:SetterValueBinding>
                        <helpers:SetterValueBinding Type="GridViewRow" Property="Background" Binding="{Binding Path=Background}" />
                    </helpers:SetterValueBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </UserControl.Resources>
      
    <Grid x:Name="LayoutRoot" Background="White">
  
        <telerik:RadGridView commands:RowEditEnded.Command="{Binding RowEditCommand}"
                             commands:RowEditEnded.CommandParameter="{Binding ElementName=ShoppingGrid, Path=SelectedItem}"
                             AutoGenerateColumns="False"
                             x:Name="ShoppingGrid"
                             ItemsSource="{Binding Path=ShoppingRecords, Mode=TwoWay}"
                             IsFilteringAllowed="False"
                             FrozenColumnCount="3"
                             RowIndicatorVisibility="Collapsed"
                             CanUserDeleteRows="False"
                             ShowGroupPanel="False"
                             RowStyle="{StaticResource RowBackgroundToggle}">
              
            <telerik:RadGridView.Columns>
                <telerik:GridViewImageColumn IsReadOnly="True" IsReorderable="False" IsResizable="False" IsSortable="False" ImageHeight="16" ImageWidth="16" ImageStretch="None" IsGroupable="False" IsFilterable="False" DataMemberBinding="{Binding Path=StatusIconPath}" Header=""/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=ReportingMark, Mode=TwoWay}" Width="85" Header="Rptg. Mark"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=CarNumber, Mode=TwoWay}" Width="85" Header="Car Number"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=ArrivalDate, Mode=TwoWay}" Width="95" Header="Arrival Date" DataFormatString="{}{0:d}"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=ShipDate, Mode=TwoWay}" Width="95" Header="Ship Date" DataFormatString="{}{0:d}"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=PODDate, Mode=TwoWay}" Width="95" Header="POD Date" DataFormatString="{}{0:d}"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=ShopCode}" Width="85" Header="Shop Code" IsReadOnly="True"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=OutboundDisposition, Mode=TwoWay}" Width="190" Header="Outbound Disposition" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=Comments, Mode=TwoWay}" Width="120" Header="Comments" />
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=CarStatusDescription}" Width="85" Header="Car Status" IsReadOnly="True"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=OwnerFMCodeValue}" Width="80" Header="Owner FM" IsReadOnly="True"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=LesseeFMCodeValue}" Width="80" Header="Lessee FM" IsReadOnly="True"/>
                <telerik:GridViewDataColumn DataMemberBinding="{Binding Path=SublesseeFMCodeValue}" Width="80" Header="Sublessee FM" IsReadOnly="True"/>
            </telerik:RadGridView.Columns>
        </telerik:RadGridView>      
      </Grid>
</UserControl>

Here's the code for my RowEditEnded command:
using System.Windows;
using System.Windows.Controls;
using Telerik.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;
  
namespace ARI.Shopping.MassUpdater.Infrastructure.Commands {
    /// <summary>
    /// This command will only fire if the edit is committed.
    /// </summary>
    public class RowEditEnded : Attachment<RadGridView, RowEditEndedBehavior, RowEditEnded> {
        private static readonly DependencyProperty BehaviorProperty = Behavior();
        public static readonly DependencyProperty CommandProperty = Command(BehaviorProperty);
        public static readonly DependencyProperty CommandParameterProperty = Parameter(BehaviorProperty);
  
        public static void SetCommand(Control control, ICommand command) { control.SetValue(CommandProperty, command); }
        public static ICommand GetCommand(Control control) { return control.GetValue(CommandProperty) as ICommand; }
        public static void SetCommandParameter(Control control, object parameter) { control.SetValue(CommandParameterProperty, parameter); }
        public static object GetCommandParameter(Control control) { return control.GetValue(CommandParameterProperty); }
    }
  
    public class RowEditEndedBehavior : CommandBehaviorBase<RadGridView> {
        public RowEditEndedBehavior(RadGridView targetObject)
            : base(targetObject) {
            targetObject.RowEditEnded += (s, e) => ExecuteCommand();
        }
    }
}

And here's the boilerplate "Attachment" class that the command inherits from:

using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Input;
using Microsoft.Practices.Composite.Presentation.Commands;
  
namespace ARI.Shopping.MassUpdater.Infrastructure.Commands {
    public class Attachment<TTarget, TBehavior, TAttachment>
        where TTarget : Control
        where TBehavior : CommandBehaviorBase<TTarget> {
        public static DependencyProperty Behavior() {
            return DependencyProperty.RegisterAttached(
                typeof(TBehavior).Name,
                typeof(TBehavior),
                typeof(TTarget),
                null);
        }
  
        public static DependencyProperty Command(DependencyProperty behaviorProperty) {
            return DependencyProperty.RegisterAttached(
                "Command",
                typeof(ICommand),
                typeof(TAttachment),
                new PropertyMetadata((target, args) => OnSetCommandCallback(target, args, behaviorProperty)));
        }
  
        public static DependencyProperty Parameter(DependencyProperty behaviorProperty) {
            return DependencyProperty.RegisterAttached(
                "CommandParameter",
                typeof(object),
                typeof(TAttachment),
                new PropertyMetadata((target, args) => OnSetParameterCallback(target, args, behaviorProperty)));
        }
  
        protected static void OnSetCommandCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e, DependencyProperty behaviorProperty) {
            var target = dependencyObject as TTarget;
            if (target == null)
                return;
  
            GetOrCreateBehavior(target, behaviorProperty).Command = e.NewValue as ICommand;
        }
  
        protected static void OnSetParameterCallback(DependencyObject dependencyObject, DependencyPropertyChangedEventArgs e, DependencyProperty behaviorProperty) {
            var target = dependencyObject as TTarget;
            if (target != null) {
                GetOrCreateBehavior(target, behaviorProperty).CommandParameter = e.NewValue;
            }
        }
  
        protected static TBehavior GetOrCreateBehavior(Control control, DependencyProperty behaviorProperty) {
            var behavior = control.GetValue(behaviorProperty) as TBehavior;
            if (behavior == null) {
                behavior = Activator.CreateInstance(typeof(TBehavior), control) as TBehavior;
                control.SetValue(behaviorProperty, behavior);
            }
  
            return behavior;
        }
    }
}

Thanks in advance for your help!

Scott W. Anderson

6 Answers, 1 is accepted

Sort by
0
Scott
Top achievements
Rank 2
answered on 11 Nov 2010, 03:10 PM
bump for posterity.
0
Scott
Top achievements
Rank 2
answered on 15 Nov 2010, 08:17 PM
Any Telerik people out there?  My company would like to buy the RadControls suite, but this issue is really giving us trouble.
0
Maya
Telerik team
answered on 16 Nov 2010, 10:41 AM
Hello Scott,

Please excuse us for the delay in our response. We have some difficulties reproducing the issue you specified. I am sending you the sample project we used for testing the problem. Furthermore, you may take a look at this short film made upon our attempts for getting the same result as you do. The ExecuteCommand() called both when using the Enter key and when another item is clicked. 
In case there is some misunderstandings according to your requirements, please share them with us, so that we could provide you with any further assistance. You may feel free to change the sample project in the way you want and post any code-snippets or necessary changes we have to make in order to reach the same settings as yours.
 

Regards,
Maya
the Telerik team
See What's New in RadControls for Silverlight in Q3 2010 on Tuesday, November 16, 2010 11:00 AM - 12:00 PM EST or 10:00 PM - 11:00 PM EST: Register here>>
0
Scott
Top achievements
Rank 2
answered on 17 Nov 2010, 10:50 PM
What version of Prism are you using?  I'm using the 2.0 version, but I noticed your using statements were different.  I downloaded your sample project, and the command isn't firing at all, regardless of enter or selected item changed.
0
Scott
Top achievements
Rank 2
answered on 18 Nov 2010, 04:19 PM
So I figured out what my problem was.  The command was always firing, however if you look at the XAML above, my CommandParameter was set to the grid's current SelectedItem.  The default toolkit grid in Silverlight doesn't actually set the "SelectedItem" property until after RowEditEnded, even when you click on another row.  However it appears that the Telerik RadGridView sets the "SelectedItem" property before RowEditEnded is fired, but only when you click on another row.  If you navigate to another row by pressing Enter, or an Arrow key, it won't set the "SelectedItem" property until after RowEditEnded.  I was able to work around this by setting my CommandParameter in the command itself instead of the XAML.  Here's the updated RowEditCommand for anyone else that encounters this issue:

public class RowEditEnded : Attachment<RadGridView, RowEditEndedBehavior, RowEditEnded> {
    private static readonly DependencyProperty BehaviorProperty = Behavior();
    public static readonly DependencyProperty CommandProperty = Command(BehaviorProperty);
    public static readonly DependencyProperty CommandParameterProperty = Parameter(BehaviorProperty);
 
    public static void SetCommand(Control control, ICommand command) { control.SetValue(CommandProperty, command); }
    public static ICommand GetCommand(Control control) { return control.GetValue(CommandProperty) as ICommand; }
    public static void SetCommandParameter(Control control, object parameter) { control.SetValue(CommandParameterProperty, parameter); }
    public static object GetCommandParameter(Control control) { return control.GetValue(CommandParameterProperty); }
}
 
public class RowEditEndedBehavior : CommandBehaviorBase<RadGridView> {
    public RowEditEndedBehavior(RadGridView targetObject)
        : base(targetObject) {
            targetObject.RowEditEnded += (s, e) => {
                CommandParameter = e.Row.DataContext;
                ExecuteCommand();
            };
    }
}
0
Maya
Telerik team
answered on 23 Nov 2010, 08:30 AM
Hello Scott,

Indeed by design the order of the events is: SelectionChanged -> RowEditEnded when editing an item and clicking on another one and vice versus when navigating with the keys. Still I am glad to see that you have found your way through. 
 

Regards,
Maya
the Telerik team
Browse the videos here>> to help you get started with RadControls for Silverlight
Tags
GridView
Asked by
Scott
Top achievements
Rank 2
Answers by
Scott
Top achievements
Rank 2
Maya
Telerik team
Share this question
or