Expanding Row Details on New Row

11 posts, 0 answers
  1. Randy
    Randy avatar
    50 posts
    Member since:
    Aug 2010

    Posted 08 Mar 2012 Link to this post

    A week or so ago I found out that I should not be using the GridViewToggleRowDetailsColumn along with the property RowDetailsVisibilityMode.  Since I am using the Column background on the GridViewToggleRowDetailsColumn  
    to help the user see that a row is new or changed, I thought it would be best to remove the RowDetailsVisibilityMode property.  I added the recommended code from another post into the SelectionChanged event so that it would show and hide the rowdetails as a row was selected - basically to function like RowDetailsVisibilityMode = "VisibleWhenSelected".  While that works fine on existing rows, it does not work on new rows.

    What is special about my usage of the grid is that I want the user to enter all of their data inside of the rowdetails and not on the grid itself.  When I don't have any editable columns on the grid, the BeginningEdit event doesn't fire.  If I add a dummy column that is editable, then I can use the BeginningEdit event and pull out the row and make the details visible.  That works, but it has other drawbacks as well.

    On each row I have a column that contains two buttons - one for a Copy and one for a Delete.  Technically the delete just sets a field on the entity as no longer active and filters the grid to not show it.  Unfortunately after adding the dummy column, when the user tries to click on the copy or delete buttons, they have to click on them twice.  The first click selects the row and the second click allows the click event to fire.

    So the next thing I tried is to put the row into edit mode when the visibility changes on the Row Details.  This seems to work well since that event fires and then the click event on copy and edit fires - all in one click, but there is another side effect.  Sometimes the row will not get out of edit mode.  I have a save button at the top of the screen that the calls SubmitChanges().  About 2% of the time, we are getting an exception when this is being called:

    Entity is currently being edited and has uncommitted changes. A call to BeginEdit must be followed by a call to EndEdit or CancelEdit before changes can be submitted.

    I have tried to add logic to CommitEdit() on the grid before the SubmitChanges is called, but that doesn't seem to help.  I have even tried to do a CancelEdit() if the CommitEdit() doesn't result in a true but that ends up clearing out fields that had data in them that were not even changed.

    Sorry for the long post, but I seem to have exhausted my ideas.  Ideally I would not have to put the row in edit mode and could avoid the exceptions.  But that means I would need to remove my dummy column and find a way to expand the row details on a new row when all columns on the grid are read-only.  The logical place in my mind to expand the RowDetails is in AddingNewData item.  But I don't have access to the row there.  I have even tried ScrollIntoViewAsync and getting the row from the callback, but the callback never happens.  Any help would be greatly appreciated.

    -Randy

  2. Maya
    Admin
    Maya avatar
    4062 posts

    Posted 09 Mar 2012 Link to this post

    Hi Randy,

    Based on the information provided, I get the impression that you require to visualize the row details of a newly added item. Am I right or am I missing something ?
    If that your requirement, you can achieve it by handling AddingNewDataItem event of the grid as follows:

    private void radgridview1_AddingNewDataItem(object sender, Telerik.Windows.Controls.GridView.GridViewAddingNewEventArgs e)
            {
                var newClub = new Club();
                e.NewObject = newClub;
                this.radgridview1.ScrollIntoViewAsync(newClub, (f) =>
                {
                    GridViewRow row = f as GridViewRow;
                    if (row != null)
                    {
                        row.DetailsVisibility = System.Windows.Visibility.Visible;
                    }
                });
            }

    Let me know in case that this does not correspond to your requirements. 

    Regards,
    Maya
    the Telerik team
    Sharpen your .NET Ninja skills! Attend Q1 webinar week and get a chance to win a license! Book your seat now >>
  3. DevCraft banner
  4. John
    John avatar
    8 posts
    Member since:
    Apr 2016

    Posted 25 Aug in reply to Maya Link to this post

    This is almost the same as my dilemma. I have the RadGridView in ReadOnly mode. Editing is all done in the RowDetails via the GridViewToggleRowDetailsColumn. That is all working fine.

    Adding a new row is triggered through an event outside the GridView. In that event, the new item is created and added to the GridView.ItemSource, and GridView.SelectedItem is set to be the new entry. This shows the new row to the user and they can click on the toggle button to expand the RowDetails and edit the data. The new item's validation requires that the user edit the data, so they must expand the RowDetails any and every time they add an item. What I want to do is automatically expand the RowDetails of the new row when it is added. I have not been able to find any event that fires after that occurs; even SelectionChanged fires before the new row actually exists. What is the right way to do this?

  5. Stefan Nenchev
    Admin
    Stefan Nenchev avatar
    281 posts

    Posted 26 Aug Link to this post

    Hi John,

    Generally, you can bind the DetailsVisibility property of the GridViewRow to a property of your business object(for instance IsExpanded):

    <telerik:BooleanToVisibilityConverter x:Key="myConverter"></telerik:BooleanToVisibilityConverter>
            <Style TargetType="telerik:GridViewRow" BasedOn="{StaticResource GridViewRowStyle}">
                <Setter Property="DetailsVisibility" Value="{Binding IsExpanded,Converter={StaticResource myConverter}}"></Setter>
            </Style>

    When adding the item to the ItemsSource collection, simply set this property to true. Would this work for you? 

    Regards,
    Stefan Nenchev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  6. John
    John avatar
    8 posts
    Member since:
    Apr 2016

    Posted 29 Aug in reply to Stefan Nenchev Link to this post

    Pardon my inexperience, but I can't find a place in the xaml where a BooleanToVisibilityConverter is allowed. I think this approach might work, but I can't get to step 1. I don't have a GridRowView definition to put it in, and Intellisense doesn't offer one in the places I would guess it belongs.

    <telerik:RadGridView . . . RowIndicatorVisibility="Collapsed" IsReadOnly="True" LoadingRowDetails="Grid_LoadingRowDetails" IsSynchronizedWithCurrentItem="true">
     <telerik:RadGridView.ItemsSource>
      <Binding Path="NetworkViews" Source="{StaticResource DataSource}" />
     </telerik:RadGridView.ItemsSource>
     <telerik:RadGridView.Columns>
      <telerik:GridViewToggleRowDetailsColumn />
      <telerik:GridViewDataColumn Header="Name" DataMemberBinding="{Binding Name}" Width="*" />
     </telerik:RadGridView.Columns>
     <telerik:RadGridView.RowDetailsTemplate>
      <DataTemplate>
       <telerik:RadTabControl . . . >
        <telerik:RadTabItem . . . >
         . . .
        </telerik:RadTabItem>
        <telerik:RadTabItem . . . >
         . . .
        </telerik:RadTabItem>
       </telerik:RadTabControl>
      </DataTemplate>
     </telerik:RadGridView.RowDetailsTemplate>
    </telerik:RadGridView>

  7. Stefan Nenchev
    Admin
    Stefan Nenchev avatar
    281 posts

    Posted 30 Aug Link to this post

    Hello John,

    Please review the sample project attached where I have applied the suggested modifications. I hope it will be useful in your scenario.

    Regards,
    Stefan Nenchev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  8. John
    John avatar
    8 posts
    Member since:
    Apr 2016

    Posted 30 Aug in reply to Stefan Nenchev Link to this post

    I need a VS 2010 version.
  9. John
    John avatar
    8 posts
    Member since:
    Apr 2016

    Posted 30 Aug in reply to John Link to this post

    Aha! A more experienced team member came up with this approach that is working:

    void AddButton_Click(object sender, RoutedEventArgs e)
    {
        var item = new ItemViewModel();
        itemCollection.Add(item);
        ItemsGrid.SelectedItem = item;
        ItemsGrid.UpdateLayout();
        var row = ItemsGrid.ItemContainerGenerator
                  .ContainerFromItem(ItemsGrid.SelectedItem) as GridViewRow;
        if (row != null)
        {
            row.DetailsVisibility = Visibility.Visible;
            row.IsExpanded = true;
        }
    }

    I think the biggest difference between this and your suggestion is that your approach has a wider application, being usable for many scenarios of which mine is just one. The above approach is restricted to the single scenario in which it is inserted. Are there other significant differences that would be smart to know?

  10. Stefan Nenchev
    Admin
    Stefan Nenchev avatar
    281 posts

    Posted 31 Aug Link to this post

    Hello John,

    The scenario you have suggested would expand the row only in case it is in the visible part of the RadGridView. As the RadGridView uses UI Virtualization for a performance boost, its rows and cells are reused for the different items so this would cause the row to not expand(as there would be no such row that has such item).

    If you intend to add a new item only when you have scrolled to the last item - the approach you suggested seems more appropriate as you don`t have to expose a property on the business object. Another possibility is to scroll to the item when you add it and then expand the row:

    var item = new Club();
               (clubsGrid.ItemsSource as ObservableCollection<Club>).Add(item);
               clubsGrid.SelectedItem = item;
               clubsGrid.UpdateLayout();
               this.clubsGrid.ScrollIntoViewAsync(this.clubsGrid.SelectedItem, null);
      
               Dispatcher.BeginInvoke(System.Windows.Threading.DispatcherPriority.Render, (Action)(() =>
               {
                   var row = clubsGrid.GetRowForItem(clubsGrid.SelectedItem);
                   if (row != null)
                   {
                       row.DetailsVisibility = Visibility.Visible;
                       row.IsExpanded = true;
                   }
               }));

    Regards,
    Stefan Nenchev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  11. Stefan Nenchev
    Admin
    Stefan Nenchev avatar
    281 posts

    Posted 31 Aug Link to this post

    Hi John,

    Please, excuse me for setting DispatcherPriority to Render in the code snippet as the feature is available only for WPF. It should work fine without it as well:

    Dispatcher.BeginInvoke((Action)(() =>
              {
                  var row = clubsGrid.GetRowForItem(clubsGrid.SelectedItem);
                  if (row != null)
                  {
                      row.DetailsVisibility = Visibility.Visible;
                      row.IsExpanded = true;
                  }
              }));

    I hope this helps.

    Regards,
    Stefan Nenchev
    Telerik by Progress
    Do you need help with upgrading your AJAX, WPF or WinForms project? Check the Telerik API Analyzer and share your thoughts.
  12. John
    John avatar
    8 posts
    Member since:
    Apr 2016

    Posted 01 Sep in reply to Stefan Nenchev Link to this post

    Thank you. That is very helpful and educational.
Back to Top
DevCraft banner