Add New Item Problem

4 posts, 0 answers
  1. Naresh
    Naresh avatar
    31 posts
    Member since:
    Mar 2009

    Posted 08 Mar 2011 Link to this post

    We have a paged RadGridView bound to a QueryableDomainServiceCollectionView property on a view model. We also have the SelectedItem property of the grid bound to a public property (CurrentCandidate) on the view model. If the user selects an item, edits it and then saves their changes all is well.

    However, if a new item is added to the collection and is committed, the  QueryableDomainServiceCollectionView reloads which in turns sets the SelectedItem of the grid to the first row of the grid which in turn resets the CurrentCandidate VM property. For reasons I won't bore you with here, we need the CurrentCandidate property to continue to be set to the newly added Candidate.

    Is there someway to stop the QueryableDomainServiceCollectionView from reloading after a new item is added? I have tried setting AutoLoad to False but that did not change the behavior described above. It did stop the round trip to the server but in the end, SelectedItem was set back to the first row in the grid.

    Any suggestions would be appreciated.

    Thank you,
    Brian


  2. Nedyalko Nikolov
    Admin
    Nedyalko Nikolov avatar
    871 posts

    Posted 12 Mar 2011 Link to this post

    Hi Brian,

    Indeed the reload of the QueryableDomainServiceCollectionView should not happen after adding a new item and we've already fixed this behavior. The fix will be available with the upcoming official release.
    With the official release assemblies you will be able to set RadGridView.SelectedItem to the newly added item.
    Be aware that there is a difference how you add a new item and you should take different action according to that.

    1. Add new item via ShowInsertRow=true, then you could handle RadGridView.RowEditEnded event and set RadGridView.SelectedItem to e.EditedItem.
    2. Add new item with ShowInsertRow = false, then you could override Enter key behavior to perform just CommitEdit command, since another commands MoveDown and select current item, will change the SelectedItem.
    For more information how to override key behavior you can take a look at this blog post.

    Let me know if this doesn't help.

    All the best,
    Nedyalko Nikolov
    the Telerik team
    Registration for Q1 2011 What’s New Webinar Week is now open. Mark your calendar for the week starting March 21st and book your seat for a walk through all the exciting stuff we ship with the new release!
  3. DevCraft banner
  4. Alexander Lev
    Alexander Lev avatar
    3 posts
    Member since:
    Nov 2009

    Posted 22 Mar 2011 Link to this post

    In the project I use Silverlight4, Telerik Q1 2011: RadGridView, MVVM, WCF RIA Service, ORM EF 4 code first CTP 5

    1. Domain Model Layer: POCO class:
    // My Register ModBus Protocol
    public
    partial class RegAssign
    {
        [Key]
        public long Id { get; set; }
        public string Code { get; set; }
        public string Description { get; set; }
        public int ModBusReg { get; set; }
        public int MinRegNum { get; set; }
        public int MaxRegNum { get; set; }
    }
    2. Data Access Layer: DbContext
    public class EFContext : DbContext
    {
            public EFContext() : base("ApplicationServices"
            {
                Configuration.LazyLoadingEnabled = false;
            }
            public DbSet<RegAssign>     RegAssigns      { get; set; }
    }
    3. Domain Service Layer: WCF RIA Service WCF RIA Services with EF4 CTP5
    RegAssignService.cs
    [EnableClientAccess()]
    public class RegAssignDomainService : DomainService
    {
        public RegAssignDomainService()
        {
            this.Container = new EFContext();
        }
        private EFContext Container { get; set; }
        protected override void Dispose(bool disposing)
        {
            if (disposing)
            {
                this.Container.Dispose();
            }
            base.Dispose(disposing);
        }
        protected override bool PersistChangeSet()
        {
            this.Container.SaveChanges();
            return base.PersistChangeSet();
        }
        public ObjectContext ObjectContext
        {
            get
            {
                return ((IObjectContextAdapter)this).ObjectContext;
            }
        }
        public IEnumerable<RegAssign> GetRegAssigns()
        {
            return this.Container.RegAssigns.OrderBy(a => a.ModBusReg).ToList();
        }
        public void InsertRegAssign(RegAssign obj)
        {
            this.Container.Insert(obj);
        }
        public void UpdateRegAssign(RegAssign currentRegAssign)
        {
            this.Container.Update(currentRegAssign, this.ChangeSet.GetOriginal(currentRegAssign));
        }
        public void DeleteRegAssign(RegAssign obj)
        {
            this.Container.Delete(obj);
        }
        private static Expression<Func<RegAssign, string>> CreateSelectorExpression(string propertyName)
        {
            var paramterExpression = Expression.Parameter(typeof(RegAssign));
            return (Expression<Func<RegAssign, string>>)Expression.Lambda(Expression.PropertyOrField(paramterExpression,   propertyName), paramterExpression);
        }
    }
    RegAssignService.metadata.cs
    [MetadataType(typeof(RegAssignMetadata))]
    public class RegAssign
    {
        #region Nested type: RegAssignMetadata
        internal sealed class RegAssignMetadata
        {
            // Metadata classes are not meant to be instantiated.
            private RegAssignMetadata()
            {
            }
            public long Id { get; set; }
            public string Code { get; set; }
            public string Description { get; set; }
            public int ModBusReg { get; set; }
            public int MinRegNum { get; set; }
            public int MaxRegNum { get; set; }
        }
        #endregion
    }
    4. Silverlight Navigate Application - View Layer:
    RegAssignView.xaml on blog's Support MVVM and Domain Data Source MVVM support
    <Grid x:Name="LayoutRoot">
            <Grid.RowDefinitions>
                <RowDefinition Height="Auto" />
                <RowDefinition />
            </Grid.RowDefinitions>
      
            <Border telerikQuickStart:ThemeAwareBackgroundBehavior.IsEnabled="True" Grid.RowSpan="2" />
      
            <StackPanel Name="ConfigurationPanel" 
                        Orientation="Horizontal" HorizontalAlignment="Center" Margin="0,5,0,0">
                <telerik:RadButton Width="150" Content="Delete selected" Margin="0,0,5,0" 
                                   Command="{Binding DeleteCommand}"
                                   CommandParameter="{Binding ElementName=mainGrid, Path=SelectedItem}"
                                   Visibility="{Binding IsDeleteCommandAvailable, Converter={StaticResource BooleanToVisibilityConverter}}"  />
                <telerik:RadButton Width="150" Content="Add New" Margin="0,0,5,0" 
                                   Command="{Binding DeleteCommand}"
                                   CommandParameter="{Binding ElementName=mainGrid, Path=SelectedItem}"
                                   Visibility="{Binding IsInsertCommandAvailable, Converter={StaticResource BooleanToVisibilityConverter}}"
                                   />
                <telerik:RadButton Width="150" Content="Save edit" Margin="0,0,5,0"
                                   Command="telerikGrid:RadGridViewCommands.CommitEdit"   
                                   CommandTarget="{Binding ElementName=mainGrid}"  />
                <telerik:RadButton Width="150" Content="Cancel edit"
                                   Command="telerikGrid:RadGridViewCommands.CancelRowEdit"   
                                   CommandTarget="{Binding ElementName=mainGrid}"  />
            </StackPanel>
                            <!-- SelectionMode="Extended" -->
            <telerik:RadGridView x:Name="mainGrid" 
                                 ItemsSource="{Binding View}" 
                                 SelectedItem="{Binding SelectedItem}"
                                 AutoGenerateColumns="False" 
                                 Margin="0,5,0,0" 
                                 Grid.Row="1" 
                                 ActionOnLostFocus="None" 
                                 CanUserDeleteRows="True"
                                 IsReadOnly="False"
                                 >
                <telerik:RadGridView.Columns>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Code}" Header="Code"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding ModBusReg}" Header="Mod Bus Register"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding MinRegNum}" Header="Min Register"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding MaxRegNum}" Header="Max Register"/>
                    <telerik:GridViewDataColumn DataMemberBinding="{Binding Description}" Header="Description" Width="*"/>
                    <telerik:GridViewColumn>
                        <telerik:GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <telerik:RadButton Content="Delete" 
                                                   Command="telerikGrid:RadGridViewCommands.Delete" 
                                                   CommandParameter="{Binding ElementName=mainGrid, Path=SelectedItem}" />
                            </DataTemplate>
                        </telerik:GridViewColumn.CellTemplate>
                    </telerik:GridViewColumn>
                </telerik:RadGridView.Columns>
            </telerik:RadGridView>
        </Grid>

    RegAssign.xaml.cs
    public partial class RegAssign : Page
    {
            public RegAssign()
            {
                InitializeComponent();
                this.mainGrid.Items.DescriptorsSynchronizationMode = SynchronizationMode.TwoWay;
                RegAssignViewModel viewModel = new RegAssignViewModel();
                this.mainGrid.DataContext = viewModel;
                this.ConfigurationPanel.DataContext = viewModel;
            }
    }


    5 View Model Layer
    RegAssignViewModel
        public class RegAssignViewModel : ViewModelBase 
        {
            private QueryableDomainServiceCollectionView<RegAssign> view;
            private IEnumerable<RegAssign> selectedItems; 
            private DelegateCommand loadCommand;
            private ICommand insertCommand;
            private ICommand deleteCommand;
            private ICommand saveCommand;
            private ICommand cancelCommand;
      
            private RegAssignDomainContext context;
      
            public RegAssignViewModel()
            {
                context = new RegAssignDomainContext();
                EntityQuery<RegAssign> getQuery = context.GetRegAssignsQuery();
                this.view = new QueryableDomainServiceCollectionView<RegAssign>(context, getQuery);
      
                this.view.PageSize = 10;
                this.view.AutoLoad = true;
                  
                this.view.PropertyChanged += this.OnViewPropertyChanged;
      
                this.loadCommand   = new DelegateCommand(this.ExecuteLoadCommand, this.LoadCommandCanExecute);
                this.insertCommand = new DelegateCommand((o) =>
                {
                    view.AddNew(o ?? new RegAssign());
                });
                    //RadGridViewCommands.BeginInsert;
                this.saveCommand    = RadGridViewCommands.CommitEdit;
                this.cancelCommand  = RadGridViewCommands.CancelRowEdit;
                this.deleteCommand  = RadGridViewCommands.Delete;
                /*
                this.insertCommand  = new DelegateCommand(this.ExecuteInsertCommand, this.InsertCommandCanExecute);
                //this.editCommand    = new DelegateCommand(this.ExecuteEditCommand, this.EditCommandCanExecute);
                this.deleteCommand  = new DelegateCommand(this.ExecuteDeleteCommand, this.DeleteCommandCanExecute);
                this.saveCommand    = new DelegateCommand(this.ExecuteSaveCommand, this.SaveCommandCanExecute);
                this.cancelCommand  = new DelegateCommand(this.ExecuteCancelCommand, this.CancelCommandCanExecute);
                 */ 
            }
      
            public IEnumerable View 
            
                get { return this.view; } 
            }
      
            public RegAssign SelectedItem
            {
                get { return (RegAssign)this.view.CurrentItem; }
            }
      
            public int PageSize
            {
                get { return this.view.PageSize; }
                set
                {
                    if (this.view.PageSize != value)
                    {
                        this.view.PageSize = value;
                        this.OnPropertyChanged(m => m.PageSize);
                    }
                }
            }
      
            public bool AutoLoad
            {
                get { return this.view.AutoLoad; }
                set 
                
                    if (this.view.AutoLoad != value)
                    {
                        this.view.AutoLoad = value;
                        this.OnPropertyChanged(m => m.AutoLoad);
                    }
                }
            }
      
            public ICommand InsertCommand 
            
                get { return insertCommand; } 
            }
    /* My unsuccessful implementation of an inserting command RadGridView
            public bool IsInsertCommandAvailable { get { return InsertCommandCanExecute(null); } }
            public ICommand InsertCommand { get { return insertCommand; } }
            private void ExecuteInsertCommand(object o)
            {
                view.AddNew((RegAssign)o ?? new RegAssign());
            }
            private bool InsertCommandCanExecute(object o)
            {
                return view.CanAddNew;
            }
    */
            public bool IsBusy { get { return view.IsBusy; } }
      
            public bool CanLoad { get { return view.CanLoad; } }
            public ICommand LoadCommand { get { return loadCommand; } }
            private void ExecuteLoadCommand(object o) 
            
                view.Load(); 
            }
            private bool LoadCommandCanExecute(object o)
            {
                return CanLoad && ! AutoLoad;
            }
      
            private void OnViewPropertyChanged(object sender, PropertyChangedEventArgs e)
            {
                switch (e.PropertyName)
                {
                    case "CanLoad":
                        this.loadCommand.InvalidateCanExecute();
                        break;
                    case "IsBusy":
                    case "AutoLoad":
                        this.OnPropertyChanged(e.PropertyName);
                        this.loadCommand.InvalidateCanExecute();
                        break;
                    default:
                        this.OnPropertyChanged(e.PropertyName);
                        break;
                }
            }

    In my View RadButtons in RadGridView does not work at any variants of a binding and implemenation of commands to ViewModel!

    My request:
    Very simple example of implementation in ViewModel CRUD сommands RadGridView 
    using magic QueryableDomainServiceCollectionView

    Thanks

  5. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 22 Mar 2011 Link to this post

    Hi Brian,

    I have replied to the other forum thread you started on the same topic.
     

    Kind regards,
    Maya
    the Telerik team
Back to Top