This question is locked. New answers and comments are not allowed.
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:
Here's the code for my RowEditEnded command:
And here's the boilerplate "Attachment" class that the command inherits from:
Thanks in advance for your help!
Scott W. Anderson
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:telerik="http://schemas.telerik.com/2008/xaml/presentation" 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