Commands in Telerik RadGridView

Mar 26, 2012 at 10:09 AM
Edited Mar 26, 2012 at 1:45 PM

Hi Geert,

I developed for quite some time in ASP.NET using de mvp pattern but now I started a new project using WPF. I started with the Simple MVVM toolkit but since it does not seem to support native nested views I moved to Catel. By coincidence you replied my post there about nested views?

I have to say I am really impressed by the framework that you have produced but also a bit intimidated since I am relative new to world of xaml, routed events/commands, control templates, dependency properties, mvvm, etc.

Anyway I refactored my project to Catel and my nested views now work fine. It is a telerik grid (main view) which shows an obsevable collection of projects. In the grid I am showing 5 instances of a view that represent a day which is an obsevable collection in de main (view)model . In that view there can be x instances of a person view which is an obsevable collection in de day view(model).

Alle have there own viewmodel and this al works fine.

Now the Issues that I ran into.

I want is to delegate a command from the mainwindowviewmodel to a child model. I have an expander in a gridrow. When a users clicks it I want an expander in the day view to expand or collapse too in the same row. It seems I can't bind commands to expanders and how can I pass the command with parameter bool IsExpanded to the child viewmodels?

My last question is about the header. I want to show a (dynamic) date there. Since it is not possible to bind the grid header I get an instance of the vm in code behind. Then I get the first project row if there is any and set it's date to the header. Is there any other way to do this?

I have downloaded the catel examples and checked the nested views example with the rooms, beds etc. In your article you have buttons to add rooms, beds etc but in the example these are missing while they could help me solve my problem. I tried to add them myself but I can't get it to work. Is it possible to share this example with the buttons us?

 

Coordinator
Mar 26, 2012 at 6:56 PM

Don't worry, I felt overwhelmed at first as well by MVVM. However, once you get the hang of it, you never want to go back :)

It looks like you are having a binding error. Binding errors are a bit difficult to debug because they do not throw exceptions, they simply don't work. What you *need* to do is to check out the output window. Binding errors are written to the output window.

A small sidenode: By default, you might see binding errors that are not valid. This is because the view loads the model as data context => shows binding errors => Catel transforms the model into a view model. This issue will be fixed in 3.1, but exists in 3.0. It does not hurt anything, you can ignore them, it just makes it a bit more difficult to find the right binding error.

1) I am trying to figure out what the expander has. Does the expander itself have a view model, or does it contain a child that has it's own view model? If you have a very small repro app, I can definitely help you out.

2) I know the telerik grid sucks a bit (you cannot bind headers). However, if you derive from a UserControl that catel delivers, you can use the OnViewModelPropertyChanged and the OnViewModelChanged. In these events, you can check whether you have a view model and update the value without a binding. I think that is the cleanest solution out there at the moment.

Mar 27, 2012 at 9:56 AM

Hi Geert,

Thanks for the reply, the output window tip was really usefull! I managed to fix my binding errors and I also found a way to bind the header.

In case someone is interested I did it like this:

                    <telerik:GridViewDataColumn.Header>
                        <TextBlock>
                            <TextBlock.Text>
                                <Binding RelativeSource="{RelativeSource AncestorType=telerik:GridViewDataControl}" Path="DataContext.Projects[0].Days[0].Date" StringFormat="{}{0:D}"/>
                            </TextBlock.Text>
                        </TextBlock>
                    </telerik:GridViewDataColumn.Header>

I am binding to a property of the first row (Projects[0]) of the object that I am binding. When there is no data you will get a binding error and the header will stay empty but in my case that is what I want. No code behind and quite simple in the end.

About the Expanders I guess I have to do something with EventToCommand, I will first try to figure this out myself.

Thanks again.

 

 


Coordinator
Mar 27, 2012 at 10:01 AM

Glad it worked out for you. Make sure to wrap the RegisterDebugListener in a #if debug like this:

#if DEBUG
    LogManager.RegisterDebugListener();
#endif

It has a huge impact on performance and should only be used for debugging purposes.

Mar 27, 2012 at 3:14 PM
Edited Mar 27, 2012 at 3:47 PM

Hi Geert,

I am still struggling with the expanders but your nested views example is a great example for what I want.

What I want is that the underlying expanders follow its parent expander behavior.

With follow behavior I mean if you expand then the underlying expenders should expand and if you collapse all underlying expanders should collapse.

So when I click the house expander I want all underlying room and table expanders to follow. And if I click a room expander I only want the underlying table expanders of this one and only room to follow its behavior. So not the other rooms or the above house.

How would you solve this?

I have bound the IsExpanded property of the expanders in the viewmodels but how can I tell that the child viewmodels to change the IsExpanded property?

Coordinator
Mar 27, 2012 at 3:17 PM

This is more a "view" behavior than a view model behavior. Therefore, it is perfectly valid to solve this in the view. What I would do in this case is use the MessageMediator. When a specific level collapses or expands, you can broadcast a message. Then all other views can respond to this.

The only thing you should keep in mind is that when you collapse an expander as a response to a broadcasted message, you don't broadcast it again (then you get lots and lots of unnecessary messages, which could have a negative impact on performance).

Mar 29, 2012 at 3:35 PM

I got it working with the messagemediator :)

I have bound the selected item in de datagrid so I know the id of my selected row. With EventToCommand I know when the Expander is doing someting and I can send a message with the id. In the child model I can check if the id is the same and if so I can set the IsExpanded property the is bound to the IsExpanded property of the child expanders. Works like a charm wit no code behind.

Coordinator
Mar 29, 2012 at 3:36 PM

Thanks for letting us know! Glad that it worked out :)

If you have any more questions, don't hesitate to contact us!