1)测试数据准备:
//这是我学习treeview绑定时用的,也随带给不是很会用treeview绑定的网友们一个例子.
A)层级类,树形结构.
public class Folder
{
public ObservableCollection<Folder> Children { get; set; }
public string A { get; set; }
public string B { get; set; }
}
B) 一个简单的ViewModel
public class MainViewModel : ViewModelBase
{
public string Welcome
{
get
{
return "Welcome to MVVM Light";
}
}
/// <summary>
/// Initializes a new instance of the MainViewModel class.
/// </summary>
public MainViewModel()
{
if (IsInDesignMode)
{
// Code runs in Blend --> create design time data.
}
else
{
LoadData();
// Code runs "for real"
}
}
public void LoadData()
{
ObservableCollection<Folder> theFolders = new ObservableCollection<Folder>();
Folder theFolder = new Folder()
{
A = "A",
B = "1001",
Children = new ObservableCollection<Folder>() {
new Folder(){A="B1",B="101",Children= new ObservableCollection<Folder>(){
new Folder(){A="C1",B="10101"},
new Folder(){A="C2",B="10102"},
}},
new Folder(){A="B2",B="102",Children= new ObservableCollection<Folder>(){
new Folder(){A="C3",B="10201"},
new Folder(){A="C4",B="10202"},
}},
new Folder(){A="B3",B="103"},
new Folder(){A="B4",B="104"},
}
};
theFolders.Add(theFolder);
theFolder = new Folder()
{
A = "B",
B = "20",
Children = new ObservableCollection<Folder>() {
new Folder(){A="B4",B="201",Children= new ObservableCollection<Folder>(){
new Folder(){A="C1",B="20101"},
new Folder(){A="C2",B="20102"},
}},
new Folder(){A="B5",B="202",Children= new ObservableCollection<Folder>(){
new Folder(){A="C3",B="20201"},
new Folder(){A="C4",B="20202"},
}},
new Folder(){A="B6",B="203"},
new Folder(){A="B7",B="204"},
}
};
theFolders.Add(theFolder);
this.Folders = theFolders;
}
private ObservableCollection<Folder> _Folders;
public ObservableCollection<Folder> Folders
{
get
{
return _Folders;
}
set
{
if (_Folders != value)
{
_Folders = value;
RaisePropertyChanged("Folders");
}
}
}
////public override void Cleanup()
////{
//// // Clean up if needed
//// base.Cleanup();
////}
}
2)下面是页面:
<UserControl x:Class="MvvmLight1.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:MvvmLight1" <!-- 这里是定义命名空间-->
mc:Ignorable="d"
Height="300"
Width="300"
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
DataContext="{Binding Main, Source={StaticResource Locator}}"
xmlns:sdk="http://schemas.microsoft.com/winfx/2006/xaml/presentation/sdk">
<UserControl.Resources>
<!-- TreeView的模板-->
<sdk:HierarchicalDataTemplate x:Key="FolderTemplate" ItemsSource="{Binding Children}">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="0.3*"></ColumnDefinition>
<ColumnDefinition Width="0.7*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Grid.Column="0" Text="{Binding Path=A}"></TextBlock>
<TextBox Grid.Column="1" Text="{Binding Path=B}"></TextBox>
</Grid>
</sdk:HierarchicalDataTemplate>
</UserControl.Resources>
<Grid x:Name="LayoutRoot">
<TextBlock FontSize="36"
FontWeight="Bold"
Foreground="Purple"
Text="{Binding Welcome}"
VerticalAlignment="Center"
HorizontalAlignment="Center"
TextWrapping="Wrap" />
<sdk:TreeView ItemsSource="{Binding Path=Folders}" ItemTemplate="{StaticResource FolderTemplate}" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="treeView1" VerticalAlignment="Stretch" SelectedItemChanged="treeView1_SelectedItemChanged" >
<!--<i:Interaction.Behaviors> 这里是用微软的behavior做.
<local:MyBehavior Params="hello,tian" TargetName="treeView1" MethodName="TreeViewSelected" />
</i:Interaction.Behaviors>-->
<!-- 这里是用我们刚才定义的Action框架实现交互TreeViewSelected选择方法定义在本页的.cs中见后面的代码,注意myactiontest的参数,这些参数在解析过程中最终会变成对应属性的值..-->
<local:WPFTestDettach.MyObjects>
<local:MyActionTest EventName="SelectedItemChanged" Params="hello,1" TargetName="" MethodName="TreeViewSelected" MyName="xxx1"></local:MyActionTest>
<local:MyActionTest EventName="SelectedItemChanged" Params="hello,2" TargetName="" MethodName="TreeViewSelected" MyName="xxx2"></local:MyActionTest>
<local:MyActionTest EventName="SelectedItemChanged" Params="hello,3" TargetName="" MethodName="TreeViewSelected" MyName="xxx3"></local:MyActionTest>
<local:MyActionTest EventName="SelectedItemChanged" Params="hello,4" TargetName="" MethodName="TreeViewSelected" MyName="xxx4"></local:MyActionTest>
</local:WPFTestDettach.MyObjects>
</sdk:TreeView>
</Grid>
</UserControl>
3)xaml.cs
public partial class MainPage : UserControl
{
public MainPage()
{
InitializeComponent();
} public void TreeViewSelected(string Params)
{
MessageBox.Show(Params);
}
}
4)我利用微软的behaviors实现,MyBehavior 继承自Behavior<>,大家可以对比一下,很多代码都比较类似.
public class MyBehavior : Behavior<TreeView>
{
protected override void OnAttached()
{
base.OnAttached();
this.AssociatedObject.SelectedItemChanged += new RoutedPropertyChangedEventHandler<object>(AssociatedObject_SelectedItemChanged);
}
void AssociatedObject_SelectedItemChanged(object sender, RoutedPropertyChangedEventArgs<object> e)
{
DoSomething(Params);
}
protected override void OnDetaching()
{
base.OnDetaching();
this.AssociatedObject.SelectedItemChanged -= new RoutedPropertyChangedEventHandler<object>(AssociatedObject_SelectedItemChanged);
}
public string Params { get; set; }
public string TargetName { get; set; }
public string MethodName { get; set; }
public void DoSomething(string PMs)
{
object theRootObj = GetRootObject(this.AssociatedObject);
object theTargetObj = null;
if (TargetName == "")
{
theTargetObj = theRootObj;
}
else
{
theTargetObj = ((FrameworkElement)theRootObj).FindName(TargetName);
}
MyActionCollection theValue = (MyActionCollection)((DependencyObject)theTargetObj).GetValue(WPFTestDettach.MyObjectsProperty);
foreach (var item in theValue)
{
string a = item.MyName;
}
MethodInfo[] theMIs = theTargetObj.GetType().GetMethods();
MethodInfo theMI = theTargetObj.GetType().GetMethod(MethodName,BindingFlags.NonPublic);
if (theMI != null)
{
theMI.Invoke(theTargetObj, null);
}
}
private FrameworkElement GetRootObject(FrameworkElement obj)
{
if (obj.Parent != null && obj.Parent is FrameworkElement)
{
return GetRootObject((FrameworkElement)(obj.Parent));
}
return obj;
}
}