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

Repurposing the new item row

7 Answers 351 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Maurice
Top achievements
Rank 1
Maurice asked on 12 Feb 2018, 01:26 PM

I want to repurpose the new item row to allow vertical editing of the grid, i.e. an edit in any cell of the new item row will be propagated down that column and the new item row's cell will be cleared after propagation to the other records.

  1. How can I keep the new item row in an editable state, removing the need to click the 'click here to add new item' placeholder
  2. Which events can I use to stop the new row addition, it seems I have to allow the addition then remove the row
  3. It would be nice to use a behavior for this (and not have to extend the grid), my other approach below is using a behavior and hooking the DataLoaded event to add the empty row

I have tried not using the new row and just adding an empty row to the data source but it doesn't play nice with descending sorting, however, most other operations seem to work ok on the minimal testing I have done. I think the new item row might be the more robust approach though.

 

Thanks,
Maurice

 

7 Answers, 1 is accepted

Sort by
0
Stefan
Telerik team
answered on 15 Feb 2018, 11:38 AM
Hello Maurice,

Thanks for the detailed explanation of your requirement.

The control does not have a built-in mechanism that corresponds exactly to such behavior. There is, however, a possible approach for achieving your goal through the RowValidating event. It exposes the Row property through which you can access the edited element before the row edit is committed. So, you should be able to fetch the input entered by the user, make a copy of this data into a new object and insert it in the source collection. Then, you can clear the property values of the edited object and return from the RowValidating event. Returning from the event will keep the row in edit mode.

Can you please give it a try? Would such an approach meet your requirements?

Regards,
Stefan
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Maurice
Top achievements
Rank 1
answered on 15 Feb 2018, 11:58 PM

Stefan, I will give it a try, once I have it working I will post the code in case others have such a requirement.

 

Regards,
Maurice

0
Maurice
Top achievements
Rank 1
answered on 19 Feb 2018, 01:09 PM

Hi Stefan,

This is not going as smoothly as I had hoped it would, I wonder if you can give me some assistance?

I have attached a sample project. The initial issues are (commented in code also):

  1. Call BeginEdit() on the GridViewNewRow instance breaks the insert row functionality, I have tried this from both GridView.OnDataLoaded (fires multiple times, is not always non-null) and GridView.RowLoaded (fires once, so a lot nicer).
  2. I can't get access to the typed data item behind the row insert in the GridView.RowValidating event to clear the data item values, although this event is not firing reliably due to issues in #1.

Edit: I cannot attach a zip, so I will paste the code here for you to create a project from.

01.using System.Windows.Interactivity;
02. 
03.using Telerik.Windows.Controls;
04.using Telerik.Windows.Controls.GridView;
05. 
06.namespace TelerikWpfApp1
07.{
08.  public class VerticalEditBehavior : Behavior<RadGridView>
09.  {
10.    protected override void OnAttached()
11.    {
12.      base.OnAttached();
13. 
14.      AssociatedObject.RowLoaded += OnRowLoaded;
15.      AssociatedObject.RowValidating += OnRowValidating;
16.    }
17. 
18.    private void OnRowLoaded(object sender, RowLoadedEventArgs e)
19.    {
20.      if (e.Row is GridViewNewRow row)
21.      {
22.        // this row breaks the new row funcitoanlity
23.        row.BeginEdit();
24.      }
25.    }
26. 
27.    private void OnRowValidating(object sender, GridViewRowValidatingEventArgs e)
28.    {
29.      if (e.Row is GridViewNewRow && e.EditOperationType == GridViewEditOperationType.Insert)
30.      {
31.        // how to access the row data item and clear its values?
32.        // the code below doesnt work as e.Row.Item is typeof(object)
33.        //foreach (var value in e.OldValues)
34.        //{
35.        //  e.Row.Item.GetType().GetProperty(value.Key).SetValue(e.Row.Item, value.Value);
36.        //}
37. 
38.      }
39.    }
40. 
41.    protected override void OnDetaching()
42.    {
43.      base.OnDetaching();
44. 
45.      AssociatedObject.RowLoaded -= OnRowLoaded;
46.      AssociatedObject.RowValidating -= OnRowValidating;
47.    }
48.  }
49.}

 

01.using System;
02.using System.Collections.ObjectModel;
03.using System.ComponentModel.DataAnnotations;
04. 
05.using Telerik.Windows.Controls;
06. 
07.namespace TelerikWpfApp1
08.{
09.  public class MainWindowViewModel : ViewModelBase
10.  {
11.    public ObservableCollection<TestRow> Rows { get; } = new ObservableCollection<TestRow>()
12.    {
13.      new TestRow { Text = "One", Number = 1, Date = DateTime.Today },
14.      new TestRow { Text = "Two", Number = 2, Date = DateTime.Today },
15.      new TestRow { Text = "Three", Number = 3, Date = DateTime.Today },
16.      new TestRow { Text = "Four", Number = 4, Date = DateTime.Today },
17.      new TestRow { Text = "Fix", Number = 5, Date = DateTime.Today },
18.      new TestRow { Text = "Six", Number = 6, Date = DateTime.Today }
19.    };
20.  }
21. 
22.  public class TestRow
23.  {
24.    public string Text { get; set; }
25. 
26.    public int? Number { get; set; }
27. 
28.    [DisplayFormat(DataFormatString = "d")]
29.    public DateTime? Date { get; set; }
30.  }
31.}

 

01.<Window x:Class="TelerikWpfApp1.MainWindow"
04.        xmlns:telerik="http://schemas.telerik.com/2008/xaml/presentation"
05.        xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
06.        xmlns:local="clr-namespace:TelerikWpfApp1"
07.        Title="MainWindow" Height="350" Width="525">
08. 
09.  <Window.DataContext>
10.    <local:MainWindowViewModel />
11.  </Window.DataContext>
12. 
13.  <telerik:RadGridView Grid.Row="1" ShowGroupPanel="False" NewRowPosition="Top" AlternationCount="2" ItemsSource="{Binding Rows}" CanUserInsertRows="True">
14.    <i:Interaction.Behaviors>
15.      <local:VerticalEditBehavior />
16.    </i:Interaction.Behaviors>
17.  </telerik:RadGridView>
18.</Window>

 

Regards,
Maurice

0
Stefan
Telerik team
answered on 20 Feb 2018, 05:18 PM
Hi Maurice,

Thank you for the update.

The data item in the event handler can be accessed by using the DataContext of the Row property.
private void clubsGrid_RowValidating(object sender, GridViewRowValidatingEventArgs e)
       {
           if (e.Row is GridViewNewRow && e.EditOperationType == GridViewEditOperationType.Insert)
           {
               var item = e.Row.DataContext as Club;
           }
       }

I am however, also experiencing trouble keeping the row in edit mode when inserting the new item. I am now working on providing you with a working solution. I will do my best to update you shortly.

Regards,
Stefan
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Stefan
Telerik team
answered on 21 Feb 2018, 03:40 PM
Hi Maurice,

I performed various approaches in my attempts to reach a working solution. Achieving such customization turned out to be not that trivial as it looked in the first place. I have attached a sample application that demonstrates an approach of using the RowEditEnded event instead. In order to keep the editing operation on the first row, I have inserted a new empty item and forced the CurrentCell of RadGridView. This would result in a second trigger of the RowEditEnded rooting from the CurrentCell, thus a check whether the previously edited item is not the same as the currently edited one has to be applied. After that, the NewRowPosition of RadGridView is set to None, so the built-in mechanism for adding a new item is available only initially.

I do understand that this solution is far from straightforward, but it is the closest one for such customization. I cannot also guarantee that it will correspond exactly to your requirements.

I hope it helps.

Regards,
Stefan
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
0
Maurice
Top achievements
Rank 1
answered on 22 Feb 2018, 12:35 AM

Hi Stefan,

Thank you for taking the time to look into this for me. I tried a basic attempt at using a new empty row but sorting (and I suspect other things, like filtering) in the grid becomes problematic using that approach. An MVP (without validation, default values, etc.) of what I need is below, it appears to work as expected except for the new row not being able to be programmatically put into edit mode. I will now try, either; simulating a user click on the PART_AlwaysVisibleNewRow or adjusting the styles and perhaps using triggers to hide that element and trigger an edit on the row ... somehow.

01.
private void clubsGrid_RowEditEnded(object sender, GridViewRowEditEndedEventArgs e)
02.    {
03.      if (e.Row is GridViewNewRow)
04.      {
05.        clubsGrid.Items.Remove(e.EditedItem);
06.      }
07.    }
08.
09.    private void clubsGrid_CellEditEnded(object sender, GridViewCellEditEndedEventArgs e)
10.    {
11.      if (e.Cell != null && e.Cell.ParentRow is GridViewNewRow)
12.      {
13.        var column = e.Cell.DataColumn.DataMemberBinding.Path.Path;
14.        var items = clubsGrid.ItemsSource as IEnumerable<object>;
15.
16.        foreach (var item in items)
17.        {
18.          item.GetType().GetProperty(column).SetValue(item, e.NewData, null);
19.        }
20.      }
21.    }

 

Regards,
 Maurice

0
Stefan
Telerik team
answered on 26 Feb 2018, 05:33 PM
Hello Maurice,

Thank you for the update.

I am sorry to hear that you are still not able to achieve the desired behavior. I can confirm that a stable solution that works as expected in all scenarios would hardly be implemented and I cannot guarantee that this is even possible. Of course, if I can be of further assistance feel free to approach me.

Have a nice week, Maurice.

Regards,
Stefan
Progress Telerik
Want to extend the target reach of your WPF applications, leveraging iOS, Android, and UWP? Try UI for Xamarin, a suite of polished and feature-rich components for the Xamarin framework, which allow you to write beautiful native mobile apps using a single shared C# codebase.
Tags
GridView
Asked by
Maurice
Top achievements
Rank 1
Answers by
Stefan
Telerik team
Maurice
Top achievements
Rank 1
Share this question
or