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

How do you get the cell or row that a GridViewToggleButton is in?

3 Answers 93 Views
GridView
This is a migrated thread and some comments may be shown as answers.
Tony
Top achievements
Rank 1
Tony asked on 16 Apr 2012, 08:11 PM
I've created a CustomGridViewToggleRowDetailsColumn class that descends from GridViewBoundColumnBase.  Its purpose is to display the row details toggle control only if the row in question contains data to be displayed in the row details.

In order to speed up the retrieval of data from my database, I have added a boolean flag to the view model object that is displayed in the RadGridView that indicates whether the object has data for the row details.  This flag is set when the row is retrieved from the database.  However, I do not want to retrieve the data for the row details at the same time.  Rather, I want to wait for the user to click on the button to expand the details and go get the data at that time.  The underlying View Model objects implement INotifyPropertyChanged, so the WPF controls get notification of changes.

The CustomGridViewToggleRowDetailsColumn class has a Click event that I want to program.  When the user clicks on the button, I want the code to check to see if the detail data has been retrieved from the database yet, and if not, to go and get it.

Here's the definition of the CustomGridViewToggleRowDetailsColumn class:

class CustomGridViewToggleRowDetailsColumn : GridViewBoundColumnBase {
  
    public static RoutedEvent ClickEvent =
        EventManager.RegisterRoutedEvent( "Click", RoutingStrategy.Bubble, typeof( ToggleRowDetailsColumnRoutedEventHandler ), typeof( CustomGridViewToggleRowDetailsColumn ) );
  
    public GridViewCell Cell { get; set; }
  
    public event RoutedEventHandler Click {
        add { AddHandler( ClickEvent, value ); }
        remove { RemoveHandler( ClickEvent, value ); }
    }
  
    public override object Header {
        get { return null; }
        set { base.Header = value; }
    }
  
    public GridViewToggleButton ToggleButton { get; set; }
  
    private Binding toggleButtonVisibility;
    public Binding ToggleButtonVisibility {
        get { return toggleButtonVisibility; }
        set { toggleButtonVisibility = value; }
    }
  
    public CustomGridViewToggleRowDetailsColumn() {
        this.EditTriggers = GridViewEditTriggers.None;
    }
  
    public override bool CanFilter() {
        return false;
    }
  
    public override bool CanGroup() {
        return false;
    }
  
    public override bool CanSort() {
        return false;
    }
  
    public override FrameworkElement CreateCellElement( GridViewCell cell, object dataItem ) {
        Cell = cell;
  
        ToggleButton = new GridViewToggleButton { 
            Margin = new System.Windows.Thickness( 3 )
        };
        ToggleButton.Click += new RoutedEventHandler( ToggleButton_Click );
  
        if ( this.DataMemberBinding != null ) {
            ToggleButton.SetBinding( GridViewToggleButton.IsCheckedProperty, this.DataMemberBinding );
        }
  
        if ( ToggleButtonVisibility != null ) {
            ToggleButton.SetBinding( GridViewToggleButton.VisibilityProperty, ToggleButtonVisibility );
        }
  
        GridViewRow row = cell.ParentRow as GridViewRow;
  
        row.SetBinding( GridViewRow.DetailsVisibilityProperty, new Binding( "IsChecked" ) { 
            Source = ToggleButton, 
            Converter = new BooleanToVisibilityConverter(), 
            Mode = BindingMode.TwoWay 
        } );
  
        return ToggleButton;
    }
  
    void ToggleButton_Click( object sender, RoutedEventArgs e ) {
        // Raise our Click event
        RoutedEventArgs newEventArgs = new ToggleRowDetailsColumnRoutedEventArgs( ClickEvent, Cell );
        RaiseEvent( newEventArgs );
    }
}
  
public class ToggleRowDetailsColumnRoutedEventArgs : RoutedEventArgs {
  
    public GridViewCell Cell { get; set; }
  
    public GridViewRow Row {
        get { return Cell.ParentRow as GridViewRow; }
    }
  
    public ToggleRowDetailsColumnRoutedEventArgs( RoutedEvent routedEvent, GridViewCell cell )
        : base( routedEvent ) {
        Cell = cell;
    }
}
  
public delegate void ToggleRowDetailsColumnRoutedEventHandler( object sender, ToggleRowDetailsColumnRoutedEventArgs e );

Here is the Click event handler that I wrote that is called when the user clicks on the toggle button for a row that has details to be displayed:

private void ExpandAlarms_Click( object sender, ToggleRowDetailsColumnRoutedEventArgs e ) {
    ReadViewModel read = e.Row.Item as ReadViewModel;
  
    if ( read.Alarms == null ) {
        read.Alarms = DataInterface.GetAlarmsForRead( read.ID );
    }
  
    e.Handled = true;
}

The problem is that the parameters to the ExpandAlarms_Click method always refer to the same row, no matter which row I click on.  I think there is something wrong, either in the ToggleButton_Click method or in the CreateCellElement method.  But I don't know what the issue could be.  I think I need to save the Cell passed to the CreateCellElement somewhere other than were I'm saving it now, but I'm not sure where that would be.

Please help

Tony

3 Answers, 1 is accepted

Sort by
0
Tony
Top achievements
Rank 1
answered on 04 May 2012, 04:17 AM
Any chance of getting some help on this issue?
0
Vlad
Telerik team
answered on 07 May 2012, 07:06 AM
Hello,

 Can you clarify why you need the event? As far as I can see you can simply bind the button to your boolean property and perform desired operation if this property value is changed.

All the best,
Vlad
the Telerik team

Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>

0
Tony
Top achievements
Rank 1
answered on 27 Jul 2012, 06:26 PM
Actually, this problem has effectively gone away due to a design change in the application.  I no longer display row details, so there's nothing to expand.

Thanks anyway.
Tags
GridView
Asked by
Tony
Top achievements
Rank 1
Answers by
Tony
Top achievements
Rank 1
Vlad
Telerik team
Share this question
or