Go to [Silverlight getting started series] Using MVVM mode (9): Want to control the TreeView node expansion in ViewModel ?, Mvvmviewmodel
After reading my blog, many children's shoes also practiced MVVM, but they found that MVVM in Silverlight practice is difficult to implement, which is much more difficult than pure CodeBehind. First, it was originally in the xaml. the CodeBehind part of cs is easy to control the interface logic. After the logic is moved to the ViewModel, it is difficult to call the CodeBind part; second, there are many views and ViewModel, or one ViewModel with multiple views.
After reading my blog, many children's shoes also practiced MVVM, but they found that MVVM in Silverlight practice is difficult to implement, which is much more difficult than pure CodeBehind. First, it was originally in the xaml. the CodeBehind part of cs is easy to control the interface logic. After the logic is moved to the ViewModel, it is difficult to call the CodeBind part; second, there are many views and ViewModel, or one ViewModel and multiple views. How do they communicate? These problems seem very complicated. In fact, it is very simple, that is, division of labor, collaboration. Find out who is responsible for what, how to abstract and isolate, and then how to use appropriate technologies to achieve it. It is not difficult to clarify these questions.
Question raised: MVVM's TreeView cannot expand the TreeNode node as needed in the ViewModel.
Today we will talk about a very common problem: Your TreeView has been implemented in the MVVM mode (see this article: [Silverlight getting started series] In Prism, TreeView implements MVVM mode and asynchronously and dynamically loads sub-nodes (WCFRiaService) When Expanded occurs )), but what if you want to automatically expand the first node after the business logic of ViewModel is loaded to the node? You can't directly call the Node. Expand () method because you are in ViewModel. What should I do? The method in this article is actually very simple. It is also the omnipotent plaster for MVVM in Silverlight to eliminate CodeBehind: DataTrigger + Behavior. (For other methods, see my previous article: [Silverlight getting started series] Using MVVM mode (9): Want to control Storyboard animation in ViewModel ?)
Solution: Eliminate the omnipotent plaster of CodeBehind by MVVM in Silverlight: DataTrigger + Behavior
First, implement a Behavior. This Behavior is to expand the Root node of the TreeView. When will this Behavior be executed? We need to execute on demand. It is executed only when it is called. Add an attribute to ViewModel to implement the INotifyPropertyChanged interface. When a logic execution in ViewModel is completed, call it to expand the node. Set this attribute to True, it is bound to the automatic notification interface. How does Behavior relate to this attribute? The Trigger is used to monitor this attribute change. When the value changes to the desired value, your Behavior is automatically executed. This is the idea.
Implementation Code
The figure above is the final XAML code. Let's take a look at the Behavior of the root node:
1: using System.Windows.Controls;
2: using System.Windows.Interactivity;
3: using System.ComponentModel;
4: using System;
5:
6: namespace SilverlightApplication1
7: {
8: [System.ComponentModel.Description("Expands Tree Root Node")]
9: public class TreeRootExpandBehavior : TargetedTriggerAction<LazyTreeView>, INotifyPropertyChanged
10: {
11: #region "Initialization"
12:
13: private LazyTreeView objTreeView;
14:
15: /// <summary>
16: /// Called after the action is attached to an AssociatedObject.
17: /// </summary>
18: protected override void OnAttached()
19: {
20: base.OnAttached();
21:
22: objTreeView = (LazyTreeView)(AssociatedObject);
23: }
24:
25: /// <summary>
26: /// Invokes the action.
27: /// </summary>
28: /// <param name="parameter">The parameter to the action. If the action does not require a parameter, the parameter may be set to a null reference.</param>
29: protected override void Invoke(object parameter)
30: {
31: ExpandRoot();
32: }
33:
34: #endregion
35:
36: #region "Expands the root"
37:
38: /// <summary>
39: /// Expands the root.
40: /// </summary>
41: private void ExpandRoot()
42: {
43: objTreeView.UpdateLayout();
44:
45: var vm = (MyViewModel) objTreeView. DataContext; // MyViewModel is the ViewModel of your TreeView.
46: if (vm == null) return;
47:
48: var root = vm. Root; // This is a public attribute of ViewModel. You may not know the principle.
49: if (vm.Root == null || vm.Root.Count == 0) return;
50:
51: var objTreeViewItem = (TreeViewItem)objTreeView.ItemContainerGenerator.ContainerFromItem(root[0]);
52: if (objTreeViewItem != null)
53: {
54: objTreeViewItem.IsExpanded = true;
55: objTreeView.UpdateLayout();
56: }
57: }
58:
59: #endregion
60:
61: #region "INotifyPropertyChanged Implementation"
62:
63: public event PropertyChangedEventHandler PropertyChanged;
64:
65: /// <summary>
66: /// Notifies the property changed.
67: /// </summary>
68: /// <param name="info">The info.</param>
69: private void NotifyPropertyChanged(String info)
70: {
71: if (PropertyChanged != null)
72: {
73: PropertyChanged(this, new PropertyChangedEventArgs(info));
74: }
75: }
76: #endregion
77: }
78: }
Add attributes to ViewModel
When a piece of logic in ViewModel needs to be called to expand the node after execution, set this attribute to True because it is bound to the automatic notification interface. How does Behavior relate to this attribute? The Trigger is used to monitor this attribute change. When the value changes to the desired value, your Behavior is automatically executed. Note that several namespaces are referenced:
1: // reference the following namespace:
2: System.Windows.Interactivity
3: Microsoft.Expression.Interactions
4:
5: // in Xaml:
6: xmlns:ei="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"
7: xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
Source code download
This article from Mainz blog, original address: http://www.cnblogs.com/Mainz/archive/2011/09/20/2182267.html