WPF架构关键技术剖析(3)--做自己的交互Action(3)

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;
        }
    }

 


原文链接: http://blog.csdn.net/hawksoft/article/details/6798963

你可能感兴趣的:(WPF架构关键技术剖析(3)--做自己的交互Action(3))