Binding Properties of Controls in a RowDetailsTemplate

7 posts, 0 answers
  1. Kelly
    Kelly avatar
    73 posts
    Member since:
    Apr 2011

    Posted 30 Sep 2011 Link to this post

    Hello,

    I'm using a RadGridView that contains a RowDetailsTemplate that contains another RadGridView. In a separate "preferences" RadWindow I'm binding a set of checkboxes, one for each column in the top-level grid so that the end-user can select which columns are displayed, thus:

    <CheckBox x:Name="mchk1" IsChecked="{Binding IsVisible, Mode=TwoWay}">Blah</CheckBox>
    I set each individual GridView column as the DataContext for its corresponding checkbox.

    I also want the user to be able to select which columns in the RowDetails gridview are visible through checkboxes in the same way. I'm very confused though, how I would bind to the grid defined in the RowDetailsTemplate. I don't load detail until requested in the RowDetailsVisibilityChanged handler for any given row. So, when a user sets preferences for which columns are displayed, any given row's RowDetail grid could be in one of three states:

    1) not loaded yet
    2) loaded and currently visible
    3) loaded but collapsed (there is GridViewToggleRowDetailsColumn that the user could use to collapse the row)

    Is this a situation that binding will work for? How would I bind a checkbox to multiple (potentially a great many) row's RowDetailTemplate grids?

    Thank you,
    KO
  2. Ivan Ivanov
    Admin
    Ivan Ivanov avatar
    1216 posts

    Posted 05 Oct 2011 Link to this post

    Hi Kelly,

    You may try introducing several static bool variables, indicating separate column's visibility that are exposed by public properties in your business object. In this way you will be able to create an instance of this type and bind it to these CheckBoxes, being able to read these changes in all of the RadGridViews at the same time. Please, do not hesitate to contact us if you encounter any obstacles while implementing this.

    Best wishes,
    Ivan Ivanov
    the Telerik team
    Explore the entire Telerik portfolio by downloading the Ultimate Collection trial package. Get it now >>
  3. Kelly
    Kelly avatar
    73 posts
    Member since:
    Apr 2011

    Posted 28 Oct 2011 Link to this post

    Ivan,

    Sorry, but I have no idea what "In this way you will be able to create an instance of this type and bind it to these CheckBoxes" means. I never directly create the GridView instances that represent my row details. I thought the top-level GridView was creating them for me.

    To simplify my question: All I'm trying to do is have a global setting that determines whether a column in the various RowDetails gridviews is visible. I want it global - not in the objects that serve as the DataContext for my rows. When the user changes a setting that says the column should not be visible, the column would disappear from all RowDetails that are expanded. When the user changes the setting back, the columns would reappear in all expanded rows. Can this be done?

    Thank you. KO
  4. Kelly
    Kelly avatar
    73 posts
    Member since:
    Apr 2011

    Posted 01 Nov 2011 Link to this post

    I finally figured out how to make this work in the code-behind.  I would still very much like to know how to bind to properties in the RowDetailsTemplate using XAML, but at least it's working now.

    If anyone else is interested, I bind the IsVisible property when each RowDetails is loaded:

    void grid_RowDetailsVisibilityChanged(object sender, GridViewRowDetailsEventArgs e)
    {
        EventMaster m = e.Row.DataContext as EventMaster;
     
        if (e.Visibility == Visibility.Visible && m.IsDetailLoaded == false)
        {
            //  This flag prevents details from being loaded more than once.
            m.IsDetailLoaded = true;
     
            //  Find the RadGridView in the set of RowDetails controls.
            DetailGrid = e.DetailsElement.FindName("details") as RadGridView;
     
            //  Create binding to a bool property in our View Model and set source
            //  to my business object.
            Binding b = new Binding("IsElapsedVisible");
            b.Source = View;
     
            // Find the column we want to change Visibility for.
            GridViewDataColumn c = DetailGrid.Columns["ElapsedTime"] as GridViewDataColumn;
     
            //  Bind to the column.
            BindingOperations.SetBinding(c, GridViewDataColumn.IsVisibleProperty, b);
     
            // Do other stuff required when RowDetails is displayed...
            ...
        }
    }
  5. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 01 Nov 2011 Link to this post

    Hello Kelly,

    The "stuff" that is inside the RowDetailsTemplate will have the respective row's data item as its DataContext. So you can bind *anything* that is inside the RowDetailsTemplate to *anything* that is on the DataContext, which is the respective data item.

    I have attached a sample project. Notice how the RowDetailsTemplate contains a grid which is bound to "Players". Players is a property on the DataContext which in this case the respective football club.

    All of these concepts are explained here.

    I hope this helps.

    All the best,
    Ross
    the Telerik team

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

  6. Kelly
    Kelly avatar
    73 posts
    Member since:
    Apr 2011

    Posted 01 Nov 2011 Link to this post

    Ross,
    Thank you for your reply, and kind consideration of my problem. When asking for help, one of the difficulties for those of us who are inexpert at Silverlight is that it is sometimes difficult to even have the language needed to express the problem. I think this current request probably falls way short, and for that I offer apologies. I can only keep trying to rephrase until I am understood.

    I know I can bind to anything in the DataContext. I'm trying to find out how to bind to something that is NOT in the DataContext, and is NOT a static resource. In short, I want to bind a RowDetails GridView control to two different objects - one that contains data, and one that contains state.

    The IsVisible property of a grid column is a perfect illustration of a problem I have with the MVVM paradigm in general. Say I have 50 columns. I find it incomprehensible that I should have to carry along 50 boolean properties in every object of the DataContext to affect the 50 columns' Visibility. Conversely, I also find it incomprehensible that I should merge the real data that is displayed in my grid rows into a business object with unrelated state information about column visibility, given that one stated purpose of MVVM is to separate the presentation from the data.

    Therefore, I want to bind the RowDetails gridview to a collection of data objects to be displayed in my rows, but bind characteristics of the GridView itself to a "state" object, one that controls such things as column visibility. I stumbled on the way to do it in code-behind, but the syntax for achieving binding to two different objects in XAML eludes me. I would like to do it there - my example above works, and looks simple because it only has to do with one column. With more than 10 columns, it is ugly, more than 25 and it's a godawful mess. Dozens and dozens and dozens of repetitive lines of code, just to make a silly column disappear. If it can be done in code-behind, I'm guessing that it can certainly be done in XAML. If not, I can certainly live with the solution I already have.

    Thanks again,

    KO
  7. Rossen Hristov
    Admin
    Rossen Hristov avatar
    2478 posts

    Posted 02 Nov 2011 Link to this post

    Hi Kelly,

    In this case your only option would be to create a new ViewModel that will contain both the actual model data and the view data (colors, visibilities, etc). For example, you can replace the Club with a new ClubViewModel, which will contain all information about the Club plus any additional view settings. In this way, inside the row details, this new ClubViewModel will be the DataContext of the child grid.

    That is the whole point of the ViewModel concept, it is the link between a View and a Model and it is perfectly fine to mix model data (i.e. Club) with view data (i.e. colors, visibilites and so on).

    I hope this helps.

    Greetings,
    Ross
    the Telerik team

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

Back to Top