Now we know all the required elements to solve the problem I've illustrated previously. The ItemsControl contains some methods we can use to manage the lifetime of the container:ģ) GetContainerForItemOverride() Solving the problem The interesting part of this structure is that we can change the container class overriding a method of the ItemsControl. This is the way the TreeView shows a hierarchical structure because every item in the control is binded to the list of children that the item must expose to continue the hierarchy. The TreeViewItem class is generated by the TreeView control and - as we said in the previous paragraph - it contains some key events like Expanded and Collapsed but also is a subclass of ItemsControl itself. When you use the ItemsControl as base of TreeView (or also of a ListBox), the control wraps every element of the source collection with a specialized item that is responsible to handle item-specific properties and behaviors. ![]() This flexible control - you may use directly into the xaml or indirectly with some major controls - is substantially capable of taking the elements of a list, attached to the ItemsSource property and apply a template to generate some UI elements. Similar to many other controls that generates its content from the data source, the TreeView inherits his behavior from the ItemsControl. This apply not only to the Expanded and Collapsed events, but also to the mouse events, like MouseLeftButtonUp and other else and virtually every other item-level event. So, the problem is that we cannot gain access to the events using DataBinding, because the TreeViewItem class is only a wrapper that is generated by the DataBinding but is not exposed by a template or some properties of the control. Using this tecnique we will have to attach every single item of the TreeView to an event handler to catch the actions and this has to be done into the codebehind of the page. This solution besides being complicated is also invalid in a MVVM application because violate a key concept of separation of concerns between the user interface and the Business logic. TreeView tv = new TreeView() TreeViewItem item = new TreeViewItem() item.Expanded += new RoutedEventHandler(item_Expanded) item.Collapsed += new RoutedEventHandler(item_Collapsed) tv.Items.Add(item) ![]() In an event-driven application is still possible to detect the expand/collapse action because the TreeViewItem class exposes the Expanded and Collapsed event so we can write something like this: The sole event that have this scope is the SelectedItemChanged event we can use to detect if the user changed the currently selected item.īut what if I need to detect when the user expands or collapses a node? The treeview completely miss this kind of events. If you scan the events of a TreeView control you will discover that it miss a series of item-level events. Understanding the problemīefore starting to analyze the solutions I will propose, it is better to understand where is the problem I would like to resolve. I was working with a SDK's TreeView control, trying to make it lazy loaded in the ViewModel and also to catch the selection of an item to publish the SelectedItem to other ViewModels. In a recent work I did, one of this not-unusual cases taken me some time to reach a solution. Also if we can rely on Prism's DelegateCommand class, to create some of the missing commands and enhance the support to the pattern, there are some cases where it is not possible to connect directly a command to an event and catch it in the ViewModel. This is not true for Silverlight, where the elective model is event-driven and this often cause the need to write code in the codebehind of the page instead of relying on commands and ViewModel. In Windows Presentation Foundation there is an extended commanding support since the first releases of the platform that enable handling many behavior of the controls and respond easily to the user interaction. The Model-View-ViewModel pattern has been introduced in Silverlight by few time and this platform lacks a complete support to the pattern by the standard controls. After some work, I found a way to change the TreeView and transform it to be lazy loadable. ![]() As usually happen, the standard controls are designed to work in an event-driven behavior and this non always marries with a correct MVVM implementation. During a recent work I found some trouble working with the TreeView control in a Model-View-ViewModel scenario.
0 Comments
Leave a Reply. |
Details
AuthorWrite something about yourself. No need to be fancy, just an overview. ArchivesCategories |