Просмотр исходного кода

行为树编辑器增加功能:1保存配置,2读取配置生成树

tanghai 11 лет назад
Родитель
Сommit
52f73b53d8

+ 193 - 198
CSharp/App/Editor/Editor.csproj

@@ -1,199 +1,194 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{C46F3337-0F48-4A72-84AD-8FDD1F159BB0}</ProjectGuid>
-    <OutputType>WinExe</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Editor</RootNamespace>
-    <AssemblyName>Editor</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <TargetFrameworkProfile>
-    </TargetFrameworkProfile>
-    <FileAlignment>512</FileAlignment>
-    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
-    <WarningLevel>4</WarningLevel>
-    <Utf8Output>true</Utf8Output>
-    <ExpressionBlendVersion>4.0.20621.0</ExpressionBlendVersion>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\CSharp\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-    <PublishUrl>发布\</PublishUrl>
-    <Install>true</Install>
-    <InstallFrom>Disk</InstallFrom>
-    <UpdateEnabled>false</UpdateEnabled>
-    <UpdateMode>Foreground</UpdateMode>
-    <UpdateInterval>7</UpdateInterval>
-    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
-    <UpdatePeriodically>false</UpdatePeriodically>
-    <UpdateRequired>false</UpdateRequired>
-    <MapFileExtensions>true</MapFileExtensions>
-    <ApplicationRevision>0</ApplicationRevision>
-    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
-    <IsWebBootstrapper>false</IsWebBootstrapper>
-    <UseApplicationTrust>false</UseApplicationTrust>
-    <BootstrapperEnabled>true</BootstrapperEnabled>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
-    <PlatformTarget>x86</PlatformTarget>
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\Bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
-    <PlatformTarget>x86</PlatformTarget>
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\Bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Practices.Prism.Composition">
-      <HintPath>..\..\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.Interactivity, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\packages\Prism.Interactivity.5.0.0\lib\NET45\Microsoft.Practices.Prism.Interactivity.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.MefExtensions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\packages\Prism.MEFExtensions.5.0.0\lib\NET45\Microsoft.Practices.Prism.MefExtensions.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.Mvvm">
-      <HintPath>..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.Mvvm.Desktop">
-      <HintPath>..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.Desktop.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.PubSubEvents">
-      <HintPath>..\..\packages\Prism.PubSubEvents.1.0.0\lib\portable-sl4+wp7+windows8+net40\Microsoft.Practices.Prism.PubSubEvents.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.SharedInterfaces">
-      <HintPath>..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.SharedInterfaces.dll</HintPath>
-    </Reference>
-    <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
-    </Reference>
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.Composition" />
-    <Reference Include="System.Configuration" />
-    <Reference Include="System.Data" />
-    <Reference Include="System.Runtime.Serialization" />
-    <Reference Include="System.ServiceModel" />
-    <Reference Include="System.Xml" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xaml">
-      <RequiredTargetFramework>4.0</RequiredTargetFramework>
-    </Reference>
-    <Reference Include="System.Xml.Linq" />
-    <Reference Include="Telerik.Windows.Controls, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Controls.Chart, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Controls.DataVisualization, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Controls.Navigation, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="Telerik.Windows.Data, Version=2013.3.1016.45, Culture=neutral, PublicKeyToken=5803cfa389c90ce7, processorArchitecture=MSIL" />
-    <Reference Include="UIAutomationProvider" />
-    <Reference Include="UIAutomationTypes" />
-    <Reference Include="WindowsBase" />
-    <Reference Include="PresentationCore" />
-    <Reference Include="PresentationFramework" />
-  </ItemGroup>
-  <ItemGroup>
-    <ApplicationDefinition Include="App.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </ApplicationDefinition>
-    <Compile Include="Bootstrapper.cs" />
-    <Compile Include="Shell.xaml.cs">
-      <DependentUpon>Shell.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="ShellViewModel.cs" />
-    <Compile Include="App.xaml.cs">
-      <DependentUpon>App.xaml</DependentUpon>
-      <SubType>Code</SubType>
-    </Compile>
-    <Page Include="Shell.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
-  <ItemGroup>
-    <AppDesigner Include="Properties\" />
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Properties\" />
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\Infrastructure\Infrastructure.csproj">
-      <Project>{48a2e149-0dac-41b4-bb54-dfbccd6d42b3}</Project>
-      <Name>Infrastructure</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Modules\Login\Login.csproj">
-      <Project>{5aa48f9a-455d-4cd8-a605-a3ac38283e60}</Project>
-      <Name>Login</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Modules\Robot\Robot.csproj">
-      <Project>{5d6ecbcd-be14-4dcb-baec-57089748b164}</Project>
-      <Name>Robot</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Modules\Tree\Tree.csproj">
-      <Project>{6cd185d1-08e0-4729-a999-2d5b57ba8193}</Project>
-      <Name>Tree</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\Modules\WCFClient\WCFClient.csproj">
-      <Project>{B07D70E7-F902-4F67-A486-B7AF27D6B813}</Project>
-      <Name>WCFClient</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="App.config">
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="NLog.config">
-      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
-      <SubType>Designer</SubType>
-    </None>
-    <None Include="Packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <BootstrapperPackage Include=".NETFramework,Version=v4.5">
-      <Visible>False</Visible>
-      <ProductName>Microsoft .NET Framework 4.5 %28x86 和 x64%29</ProductName>
-      <Install>true</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
-      <Visible>False</Visible>
-      <ProductName>.NET Framework 3.5 SP1</ProductName>
-      <Install>false</Install>
-    </BootstrapperPackage>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PreBuildEvent>
-    </PreBuildEvent>
-  </PropertyGroup>
-  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
-  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
-       Other similar extension points exist, see Microsoft.Common.targets.
-  <Target Name="BeforeBuild">
-  </Target>
-  <Target Name="AfterBuild">
-  </Target>
-  -->
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">x86</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{C46F3337-0F48-4A72-84AD-8FDD1F159BB0}</ProjectGuid>
+    <OutputType>WinExe</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Editor</RootNamespace>
+    <AssemblyName>Editor</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <TargetFrameworkProfile>
+    </TargetFrameworkProfile>
+    <FileAlignment>512</FileAlignment>
+    <ProjectTypeGuids>{60dc8134-eba5-43b8-bcc9-bb4bc16c2548};{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}</ProjectTypeGuids>
+    <WarningLevel>4</WarningLevel>
+    <Utf8Output>true</Utf8Output>
+    <ExpressionBlendVersion>4.0.20621.0</ExpressionBlendVersion>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\CSharp\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+    <PublishUrl>发布\</PublishUrl>
+    <Install>true</Install>
+    <InstallFrom>Disk</InstallFrom>
+    <UpdateEnabled>false</UpdateEnabled>
+    <UpdateMode>Foreground</UpdateMode>
+    <UpdateInterval>7</UpdateInterval>
+    <UpdateIntervalUnits>Days</UpdateIntervalUnits>
+    <UpdatePeriodically>false</UpdatePeriodically>
+    <UpdateRequired>false</UpdateRequired>
+    <MapFileExtensions>true</MapFileExtensions>
+    <ApplicationRevision>0</ApplicationRevision>
+    <ApplicationVersion>1.0.0.%2a</ApplicationVersion>
+    <IsWebBootstrapper>false</IsWebBootstrapper>
+    <UseApplicationTrust>false</UseApplicationTrust>
+    <BootstrapperEnabled>true</BootstrapperEnabled>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\Bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|x86' ">
+    <PlatformTarget>x86</PlatformTarget>
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\Bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Practices.Prism.Composition">
+      <HintPath>..\..\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.Interactivity, Version=4.1.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\Prism.Interactivity.5.0.0\lib\NET45\Microsoft.Practices.Prism.Interactivity.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.MefExtensions, Version=5.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\Prism.MEFExtensions.5.0.0\lib\NET45\Microsoft.Practices.Prism.MefExtensions.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.Mvvm">
+      <HintPath>..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.Mvvm.Desktop">
+      <HintPath>..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.Desktop.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.PubSubEvents">
+      <HintPath>..\..\packages\Prism.PubSubEvents.1.0.0\lib\portable-sl4+wp7+windows8+net40\Microsoft.Practices.Prism.PubSubEvents.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.SharedInterfaces">
+      <HintPath>..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.SharedInterfaces.dll</HintPath>
+    </Reference>
+    <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.3.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
+    </Reference>
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Configuration" />
+    <Reference Include="System.Data" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.ServiceModel" />
+    <Reference Include="System.Xml" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Xaml">
+      <RequiredTargetFramework>4.0</RequiredTargetFramework>
+    </Reference>
+    <Reference Include="System.Xml.Linq" />
+    <Reference Include="UIAutomationProvider" />
+    <Reference Include="UIAutomationTypes" />
+    <Reference Include="WindowsBase" />
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+  </ItemGroup>
+  <ItemGroup>
+    <ApplicationDefinition Include="App.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </ApplicationDefinition>
+    <Compile Include="Bootstrapper.cs" />
+    <Compile Include="Shell.xaml.cs">
+      <DependentUpon>Shell.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="ShellViewModel.cs" />
+    <Compile Include="App.xaml.cs">
+      <DependentUpon>App.xaml</DependentUpon>
+      <SubType>Code</SubType>
+    </Compile>
+    <Page Include="Shell.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <AppDesigner Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\Infrastructure\Infrastructure.csproj">
+      <Project>{48a2e149-0dac-41b4-bb54-dfbccd6d42b3}</Project>
+      <Name>Infrastructure</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Modules\Login\Login.csproj">
+      <Project>{5aa48f9a-455d-4cd8-a605-a3ac38283e60}</Project>
+      <Name>Login</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Modules\Robot\Robot.csproj">
+      <Project>{5d6ecbcd-be14-4dcb-baec-57089748b164}</Project>
+      <Name>Robot</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Modules\Tree\Tree.csproj">
+      <Project>{6cd185d1-08e0-4729-a999-2d5b57ba8193}</Project>
+      <Name>Tree</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\Modules\WCFClient\WCFClient.csproj">
+      <Project>{B07D70E7-F902-4F67-A486-B7AF27D6B813}</Project>
+      <Name>WCFClient</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="App.config">
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="NLog.config">
+      <CopyToOutputDirectory>Always</CopyToOutputDirectory>
+      <SubType>Designer</SubType>
+    </None>
+    <None Include="Packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <BootstrapperPackage Include=".NETFramework,Version=v4.5">
+      <Visible>False</Visible>
+      <ProductName>Microsoft .NET Framework 4.5 %28x86 和 x64%29</ProductName>
+      <Install>true</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Client.3.5">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1 Client Profile</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+    <BootstrapperPackage Include="Microsoft.Net.Framework.3.5.SP1">
+      <Visible>False</Visible>
+      <ProductName>.NET Framework 3.5 SP1</ProductName>
+      <Install>false</Install>
+    </BootstrapperPackage>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+  </PropertyGroup>
+  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+  <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
+       Other similar extension points exist, see Microsoft.Common.targets.
+  <Target Name="BeforeBuild">
+  </Target>
+  <Target Name="AfterBuild">
+  </Target>
+  -->
 </Project>

+ 2 - 2
CSharp/App/Modules/Tree/BehaviorTreeLayout.cs

@@ -128,8 +128,8 @@ namespace Tree
 			treeNode.Prelim = prelim;
 			treeNode.Modify = modify;
 
-			Log.Debug("Num: " + treeNode.Num + " Prelim: " + treeNode.Prelim + " Modify: " +
-				treeNode.Modify);
+			// Log.Debug("Id: " + treeNode.Id + " Prelim: " + treeNode.Prelim + " Modify: " +
+			// 	treeNode.Modify);
 		}
 
 		private static void CalculateRelativeXAndY(

+ 9 - 4
CSharp/App/Modules/Tree/BehaviorTreeView.xaml

@@ -17,8 +17,10 @@
 	</UserControl.Resources>
 
 	<UserControl.CommandBindings>
-		<CommandBinding Command="ApplicationCommands.New" Executed="MenuNewNode_Executed" />
-		<CommandBinding Command="ApplicationCommands.Delete" Executed="MenuDeleteNode_Executed" />
+		<CommandBinding Command="ApplicationCommands.New" Executed="MenuNode_New" />
+		<CommandBinding Command="ApplicationCommands.Delete" Executed="MenuNode_Delete" />
+		<CommandBinding Command="ApplicationCommands.Save" Executed="MenuNode_Save" />
+		<CommandBinding Command="ApplicationCommands.Open" Executed="MenuNode_Open" />
 	</UserControl.CommandBindings>
 
 	<UserControl.ContextMenu>
@@ -27,6 +29,10 @@
 					CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
 			<MenuItem Header="删除" Command="ApplicationCommands.Delete"
 					CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
+			<MenuItem Header="保存" Command="ApplicationCommands.Save"
+					CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
+			<MenuItem Header="打开" Command="ApplicationCommands.Open"
+					CommandTarget="{Binding Path=PlacementTarget, RelativeSource={RelativeSource AncestorType=ContextMenu}}" />
 		</ContextMenu>
 	</UserControl.ContextMenu>
 	<Grid>
@@ -49,8 +55,7 @@
 							PreviewMouseLeftButtonUp="ListBoxItem_PreviewMouseLeftButtonUp">
 						<Rectangle Name="rectNode" Width="{Binding Width}" Height="{Binding Height}" Cursor="Hand" StrokeThickness="2"
 								RadiusX="40" RadiusY="40" Stroke="{StaticResource treeNodeBorderBrush}" Fill="{StaticResource treeNodeFillBrush}"/>
-						<Label Content="{Binding ParentNum}" Canvas.Left="20" Canvas.Top="5"></Label>
-						<Label Content="{Binding Num}" Canvas.Left="20" Canvas.Top="15"></Label>
+						<Label Content="{Binding Id}" Canvas.Left="20" Canvas.Top="15"></Label>
 						<Line X1="{Binding ConnectorX1}" Y1="{Binding ConnectorY1}" X2="{Binding ConnectorX2}" Y2="{Binding ConnectorY2}"
 								Stroke="Black" StrokeThickness="2"  />
 					</Canvas>

+ 20 - 9
CSharp/App/Modules/Tree/BehaviorTreeView.xaml.cs

@@ -37,29 +37,30 @@ namespace Tree
 			}
 		}
 
-		private void MenuNewNode_Executed(object sender, ExecutedRoutedEventArgs e)
+		private void MenuNode_New(object sender, ExecutedRoutedEventArgs e)
 		{
 			Point point = Mouse.GetPosition(this.listBox);
-			var treeNode = new TreeNode{ X = point.X, Y = point.Y};
 
 			// one root node
 			if (this.ViewModel.TreeNodes.Count == 0)
-			{
-				this.ViewModel.Add(treeNode, null);
+			{
+				var addTreeNode = new TreeNodeViewModel(point.X, point.Y);
+				this.ViewModel.Add(addTreeNode, null);
 			}
 			else
 			{
 				if (this.listBox.SelectedItem != null)
 				{
-					var treeNodeViewModel = this.listBox.SelectedItem as TreeNodeViewModel;
-					this.ViewModel.Add(treeNode, treeNodeViewModel);
+					var parentNode = this.listBox.SelectedItem as TreeNodeViewModel;
+					var addTreeNode = new TreeNodeViewModel(parentNode);
+					this.ViewModel.Add(addTreeNode, parentNode);
 				}
 			}
 			this.listBox.SelectedItem = null;
 			e.Handled = true;
 		}
 
-		private void MenuDeleteNode_Executed(object sender, ExecutedRoutedEventArgs e)
+		private void MenuNode_Delete(object sender, ExecutedRoutedEventArgs e)
 		{
 			if (this.listBox.SelectedItem == null)
 			{
@@ -69,6 +70,16 @@ namespace Tree
 			this.ViewModel.Remove(treeNodeViewModel);
 			this.listBox.SelectedItem = null;
 			e.Handled = true;
+		}
+
+		private void MenuNode_Save(object sender, ExecutedRoutedEventArgs e)
+		{
+			this.ViewModel.Save("node.bytes");
+		}
+
+		private void MenuNode_Open(object sender, ExecutedRoutedEventArgs e)
+		{
+			this.ViewModel.Load("node.bytes");
 		}
 
 		private void ListBoxItem_MouseDown(object sender, MouseButtonEventArgs e)
@@ -184,8 +195,8 @@ namespace Tree
 			}
 			var item = (FrameworkElement)sender;
 			var moveToNode = item.DataContext as TreeNodeViewModel;
-			Log.Debug("move to node: {0} {1}", moveFromNode.Num, moveToNode.Num);
-			if (this.moveFromNode.Num == moveToNode.Num)
+			Log.Debug("move to node: {0} {1}", moveFromNode.Id, moveToNode.Id);
+			if (this.moveFromNode.Id == moveToNode.Id)
 			{
 				return;
 			}

+ 76 - 24
CSharp/App/Modules/Tree/BehaviorTreeViewModel.cs

@@ -1,7 +1,8 @@
-using System.Collections.Generic;
-using System.Collections.ObjectModel;
-using System.ComponentModel.Composition;
-
+using System.Collections.ObjectModel;
+using System.ComponentModel.Composition;
+using System.IO;
+using Helper;
+
 namespace Tree
 {
 	[Export(contractType: typeof (BehaviorTreeViewModel)),
@@ -25,20 +26,19 @@ namespace Tree
 			{
 				return this.treeNodes.Count == 0? null : this.treeNodes[0];
 			}
-		}
-
-		public void Add(TreeNode treeNode, TreeNodeViewModel parent)
+		}
+
+		public void Add(TreeNodeViewModel treeNode, TreeNodeViewModel parent)
 		{
 			// 如果父节点是折叠的,需要先展开父节点
 			if (parent != null && parent.IsFolder)
 			{
 				UnFold(parent);
-			}
-			var treeNodeViewModel = new TreeNodeViewModel(treeNode, parent);
-			this.treeNodes.Add(treeNodeViewModel);
+			}
+			this.treeNodes.Add(treeNode);
 			if (parent != null)
-			{
-				parent.Children.Add(treeNodeViewModel);
+			{
+				parent.Children.Add(treeNode);
 			}
 			BehaviorTreeLayout.ExcuteLayout(this.Root);
 		}
@@ -76,16 +76,6 @@ namespace Tree
 
 		public void MoveToNode(TreeNodeViewModel from, TreeNodeViewModel to)
 		{
-			if (from.IsFolder)
-			{
-				this.UnFold(from);
-			}
-
-			if (to.IsFolder)
-			{
-				this.UnFold(to);
-			}
-
 			// from节点不能是to节点的父级节点
 			TreeNodeViewModel tmpNode = to;
 			while (tmpNode != null)
@@ -94,12 +84,22 @@ namespace Tree
 				{
 					break;
 				}
-				if (tmpNode.Num == from.Num)
+				if (tmpNode.Id == from.Id)
 				{
 					return;
 				}
 				tmpNode = tmpNode.Parent;
 			}
+
+			if (from.IsFolder)
+			{
+				this.UnFold(from);
+			}
+
+			if (to.IsFolder)
+			{
+				this.UnFold(to);
+			}
 			from.Parent.Children.Remove(from);
 			to.Children.Add(from);
 			from.Parent = to;
@@ -121,7 +121,7 @@ namespace Tree
 		}
 
 		/// <summary>
-		/// 展开节点
+		/// 展开节点,一级一级展开,一次只展开下层子节点,比如下层节点是折叠的,那下下层节点不展开
 		/// </summary>
 		/// <param name="unFoldNode"></param>
 		public void UnFold(TreeNodeViewModel unFoldNode)
@@ -150,6 +150,58 @@ namespace Tree
 			{
 				this.RecursionAdd(tn);
 			}
+		}
+
+		/// <summary>
+		/// 序列化保存
+		/// </summary>
+		public void Save(string filePath)
+		{
+			var treeNodeDataArray = new TreeNodeDataArray();
+			RecursionSave(treeNodeDataArray, this.Root);
+			byte[] bytes = ProtobufHelper.ToBytes(treeNodeDataArray);
+			using (Stream stream = new FileStream(filePath, FileMode.Create, FileAccess.Write))
+			{
+				stream.Write(bytes, 0, bytes.Length);
+			}
+		}
+
+		private void RecursionSave(TreeNodeDataArray treeNodeDataArray, TreeNodeViewModel node)
+		{
+			if (node == null)
+			{
+				return;
+			}
+			treeNodeDataArray.Add(node.TreeNodeData);
+			foreach (TreeNodeViewModel childNode in node.Children)
+			{
+				RecursionSave(treeNodeDataArray, childNode);
+			}
+		}
+
+		/// <summary>
+		/// 从配置中加载
+		/// </summary>
+		/// <param name="filePath"></param>
+		public void Load(string filePath)
+		{
+			this.TreeNodes.Clear();
+			byte[] bytes = File.ReadAllBytes(filePath);
+			var treeNodeDataArray = ProtobufHelper.FromBytes<TreeNodeDataArray>(bytes);
+			treeNodeDataArray.Init();
+			RecursionLoad(treeNodeDataArray, treeNodeDataArray.TreeNodeDatas[0], null);
+		}
+
+		private void RecursionLoad(TreeNodeDataArray treeNodeDataArray, TreeNodeData treeNodeData, TreeNodeViewModel parentNode)
+		{
+			var node = new TreeNodeViewModel(treeNodeData, parentNode);
+			this.Add(node, parentNode);
+			foreach (int id in treeNodeData.ChildrenId)
+			{
+				TreeNodeData childNodeData = treeNodeDataArray[id];
+				RecursionLoad(treeNodeDataArray, childNodeData, node);
+			}
+			BehaviorTreeLayout.ExcuteLayout(this.Root);
 		}
 	}
 }

+ 128 - 122
CSharp/App/Modules/Tree/Tree.csproj

@@ -1,129 +1,135 @@
-<?xml version="1.0" encoding="utf-8"?>
-<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
-  <PropertyGroup>
-    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
-    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
-    <ProductVersion>8.0.30703</ProductVersion>
-    <SchemaVersion>2.0</SchemaVersion>
-    <ProjectGuid>{6CD185D1-08E0-4729-A999-2D5B57BA8193}</ProjectGuid>
-    <OutputType>Library</OutputType>
-    <AppDesignerFolder>Properties</AppDesignerFolder>
-    <RootNamespace>Modules.Tree</RootNamespace>
-    <AssemblyName>Tree</AssemblyName>
-    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
-    <FileAlignment>512</FileAlignment>
-    <Utf8Output>true</Utf8Output>
-    <ExpressionBlendVersion>4.0.20621.0</ExpressionBlendVersion>
-    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\CSharp\</SolutionDir>
-    <RestorePackages>true</RestorePackages>
-    <TargetFrameworkProfile />
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
-    <DebugSymbols>true</DebugSymbols>
-    <DebugType>full</DebugType>
-    <Optimize>false</Optimize>
-    <OutputPath>..\..\..\Bin\Debug\</OutputPath>
-    <DefineConstants>DEBUG;TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
-    <DebugType>pdbonly</DebugType>
-    <Optimize>true</Optimize>
-    <OutputPath>..\..\..\Bin\Release\</OutputPath>
-    <DefineConstants>TRACE</DefineConstants>
-    <ErrorReport>prompt</ErrorReport>
-    <WarningLevel>4</WarningLevel>
-    <Prefer32Bit>false</Prefer32Bit>
-  </PropertyGroup>
-  <ItemGroup>
-    <Reference Include="Microsoft.Practices.Prism.Composition">
-      <HintPath>..\..\..\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.Interactivity">
-      <HintPath>..\..\..\packages\Prism.Interactivity.5.0.0\lib\NET45\Microsoft.Practices.Prism.Interactivity.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.MefExtensions">
-      <HintPath>..\..\..\packages\Prism.MEFExtensions.5.0.0\lib\NET45\Microsoft.Practices.Prism.MefExtensions.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.Mvvm">
-      <HintPath>..\..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.Mvvm.Desktop">
-      <HintPath>..\..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.Desktop.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.PubSubEvents">
-      <HintPath>..\..\..\packages\Prism.PubSubEvents.1.0.0\lib\portable-sl4+wp7+windows8+net40\Microsoft.Practices.Prism.PubSubEvents.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.Prism.SharedInterfaces">
-      <HintPath>..\..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.SharedInterfaces.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
-      <SpecificVersion>False</SpecificVersion>
-      <HintPath>..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
-      <Private>True</Private>
-    </Reference>
-    <Reference Include="PresentationCore" />
-    <Reference Include="PresentationFramework" />
-    <Reference Include="System" />
-    <Reference Include="System.ComponentModel.Composition" />
-    <Reference Include="System.Core" />
-    <Reference Include="System.Xaml" />
-    <Reference Include="System.Xml" />
-    <Reference Include="WindowsBase" />
-  </ItemGroup>
-  <ItemGroup>
-    <Compile Include="BehaviorTreeLayout.cs" />
-    <Compile Include="BehaviorTreeViewModel.cs" />
-    <Compile Include="BehaviorTreeModule.cs" />
-    <Compile Include="BehaviorTreeView.xaml.cs">
-      <DependentUpon>BehaviorTreeView.xaml</DependentUpon>
-    </Compile>
-    <Compile Include="TreeNode.cs" />
-    <Compile Include="TreeNodeViewModel.cs" />
-  </ItemGroup>
-  <ItemGroup>
-    <Folder Include="Properties\" />
-  </ItemGroup>
-  <ItemGroup>
-    <None Include="app.config" />
-    <None Include="Packages.config" />
-  </ItemGroup>
-  <ItemGroup>
-    <Page Include="BehaviorTreeView.xaml">
-      <Generator>MSBuild:Compile</Generator>
-      <SubType>Designer</SubType>
-    </Page>
-  </ItemGroup>
-  <ItemGroup>
-    <ProjectReference Include="..\..\..\Platform\Logger\Logger.csproj">
-      <Project>{72e16572-fc1f-4a9e-bc96-035417239298}</Project>
-      <Name>Logger</Name>
-    </ProjectReference>
-    <ProjectReference Include="..\..\Infrastructure\Infrastructure.csproj">
-      <Project>{48a2e149-0dac-41b4-bb54-dfbccd6d42b3}</Project>
-      <Name>Infrastructure</Name>
-    </ProjectReference>
-  </ItemGroup>
-  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
-  <PropertyGroup>
-    <PreBuildEvent>
-    </PreBuildEvent>
-  </PropertyGroup>
-  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
+<?xml version="1.0" encoding="utf-8"?>
+<Project ToolsVersion="4.0" DefaultTargets="Build" xmlns="http://schemas.microsoft.com/developer/msbuild/2003">
+  <PropertyGroup>
+    <Configuration Condition=" '$(Configuration)' == '' ">Debug</Configuration>
+    <Platform Condition=" '$(Platform)' == '' ">AnyCPU</Platform>
+    <ProductVersion>8.0.30703</ProductVersion>
+    <SchemaVersion>2.0</SchemaVersion>
+    <ProjectGuid>{6CD185D1-08E0-4729-A999-2D5B57BA8193}</ProjectGuid>
+    <OutputType>Library</OutputType>
+    <AppDesignerFolder>Properties</AppDesignerFolder>
+    <RootNamespace>Modules.Tree</RootNamespace>
+    <AssemblyName>Tree</AssemblyName>
+    <TargetFrameworkVersion>v4.5</TargetFrameworkVersion>
+    <FileAlignment>512</FileAlignment>
+    <Utf8Output>true</Utf8Output>
+    <ExpressionBlendVersion>4.0.20621.0</ExpressionBlendVersion>
+    <SolutionDir Condition="$(SolutionDir) == '' Or $(SolutionDir) == '*Undefined*'">..\..\..\CSharp\</SolutionDir>
+    <RestorePackages>true</RestorePackages>
+    <TargetFrameworkProfile />
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
+    <DebugSymbols>true</DebugSymbols>
+    <DebugType>full</DebugType>
+    <Optimize>false</Optimize>
+    <OutputPath>..\..\..\Bin\Debug\</OutputPath>
+    <DefineConstants>DEBUG;TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
+    <DebugType>pdbonly</DebugType>
+    <Optimize>true</Optimize>
+    <OutputPath>..\..\..\Bin\Release\</OutputPath>
+    <DefineConstants>TRACE</DefineConstants>
+    <ErrorReport>prompt</ErrorReport>
+    <WarningLevel>4</WarningLevel>
+    <Prefer32Bit>false</Prefer32Bit>
+  </PropertyGroup>
+  <ItemGroup>
+    <Reference Include="Microsoft.Practices.Prism.Composition">
+      <HintPath>..\..\..\packages\Prism.Composition.5.0.0\lib\NET45\Microsoft.Practices.Prism.Composition.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.Interactivity">
+      <HintPath>..\..\..\packages\Prism.Interactivity.5.0.0\lib\NET45\Microsoft.Practices.Prism.Interactivity.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.MefExtensions">
+      <HintPath>..\..\..\packages\Prism.MEFExtensions.5.0.0\lib\NET45\Microsoft.Practices.Prism.MefExtensions.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.Mvvm">
+      <HintPath>..\..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.Mvvm.Desktop">
+      <HintPath>..\..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.Mvvm.Desktop.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.PubSubEvents">
+      <HintPath>..\..\..\packages\Prism.PubSubEvents.1.0.0\lib\portable-sl4+wp7+windows8+net40\Microsoft.Practices.Prism.PubSubEvents.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.Prism.SharedInterfaces">
+      <HintPath>..\..\..\packages\Prism.Mvvm.1.0.0\lib\net45\Microsoft.Practices.Prism.SharedInterfaces.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="Microsoft.Practices.ServiceLocation, Version=1.0.0.0, Culture=neutral, PublicKeyToken=31bf3856ad364e35, processorArchitecture=MSIL">
+      <SpecificVersion>False</SpecificVersion>
+      <HintPath>..\..\..\packages\CommonServiceLocator.1.3\lib\portable-net4+sl5+netcore45+wpa81+wp8\Microsoft.Practices.ServiceLocation.dll</HintPath>
+      <Private>True</Private>
+    </Reference>
+    <Reference Include="PresentationCore" />
+    <Reference Include="PresentationFramework" />
+    <Reference Include="System" />
+    <Reference Include="System.ComponentModel.Composition" />
+    <Reference Include="System.Core" />
+    <Reference Include="System.Runtime.Serialization" />
+    <Reference Include="System.Xaml" />
+    <Reference Include="System.Xml" />
+    <Reference Include="WindowsBase" />
+  </ItemGroup>
+  <ItemGroup>
+    <Compile Include="BehaviorTreeLayout.cs" />
+    <Compile Include="BehaviorTreeViewModel.cs" />
+    <Compile Include="BehaviorTreeModule.cs" />
+    <Compile Include="BehaviorTreeView.xaml.cs">
+      <DependentUpon>BehaviorTreeView.xaml</DependentUpon>
+    </Compile>
+    <Compile Include="TreeNodeData.cs" />
+    <Compile Include="TreeNodeDataArray.cs" />
+    <Compile Include="TreeNodeViewModel.cs" />
+  </ItemGroup>
+  <ItemGroup>
+    <Folder Include="Properties\" />
+  </ItemGroup>
+  <ItemGroup>
+    <None Include="app.config" />
+    <None Include="Packages.config" />
+  </ItemGroup>
+  <ItemGroup>
+    <Page Include="BehaviorTreeView.xaml">
+      <Generator>MSBuild:Compile</Generator>
+      <SubType>Designer</SubType>
+    </Page>
+  </ItemGroup>
+  <ItemGroup>
+    <ProjectReference Include="..\..\..\Platform\Helper\Helper.csproj">
+      <Project>{24233CD5-A5DF-484B-A482-B79CB7A0D9CB}</Project>
+      <Name>Helper</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\..\Platform\Logger\Logger.csproj">
+      <Project>{72e16572-fc1f-4a9e-bc96-035417239298}</Project>
+      <Name>Logger</Name>
+    </ProjectReference>
+    <ProjectReference Include="..\..\Infrastructure\Infrastructure.csproj">
+      <Project>{48a2e149-0dac-41b4-bb54-dfbccd6d42b3}</Project>
+      <Name>Infrastructure</Name>
+    </ProjectReference>
+  </ItemGroup>
+  <Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
+  <PropertyGroup>
+    <PreBuildEvent>
+    </PreBuildEvent>
+  </PropertyGroup>
+  <Import Project="$(SolutionDir)\.nuget\nuget.targets" />
   <!-- To modify your build process, add your task inside one of the targets below and uncomment it. 
        Other similar extension points exist, see Microsoft.Common.targets.
   <Target Name="BeforeBuild">
   </Target>
   <Target Name="AfterBuild">
   </Target>
-  -->
+  -->
 </Project>

+ 0 - 29
CSharp/App/Modules/Tree/TreeNode.cs

@@ -1,29 +0,0 @@
-using System.Collections.Generic;
-
-namespace Tree
-{
-	public class TreeNode
-	{
-		private readonly List<int> childIds = new List<int>();
-
-		public double X { get; set; }
-
-		public double Y { get; set; }
-
-		public int Type { get; set; }
-
-		public int Id { get; set; }
-
-		public bool IsFold { get; set; }
-
-		public int ParentId { get; set; }
-
-		public List<int> ChildIds
-		{
-			get
-			{
-				return this.childIds;
-			}
-		}
-	}
-}

+ 64 - 0
CSharp/App/Modules/Tree/TreeNodeData.cs

@@ -0,0 +1,64 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace Tree
+{
+	[DataContract]
+	public class TreeNodeData
+	{
+		private readonly List<int> childrenId = new List<int>();
+
+		/// <summary>
+		/// 节点唯一Id
+		/// </summary>
+		[DataMember(Order = 1)]
+		public int Id { get; set; }
+
+		/// <summary>
+		/// 节点类型
+		/// </summary>
+		[DataMember(Order = 2)]
+		public int Type { get; set; }
+
+		/// <summary>
+		/// 节点名字
+		/// </summary>
+		[DataMember(Order = 3)]
+		public int Name { get; set; }
+
+		/// <summary>
+		/// 节点配置参数
+		/// </summary>
+		[DataMember(Order = 4)]
+		public string Args { get; set; }
+
+		/// <summary>
+		/// 父节点
+		/// </summary>
+		[DataMember(Order = 5)]
+		public int ParentId { get; set; }
+
+		/// <summary>
+		/// 子节点
+		/// </summary>
+		[DataMember(Order = 6)]
+		public List<int> ChildrenId
+		{
+			get
+			{
+				return this.childrenId;
+			}
+		}
+
+		/// <summary>
+		/// 节点说明
+		/// </summary>
+		[DataMember(Order = 7)]
+		public int Comment { get; set; }
+
+		/// <summary>
+		/// 节点是否折叠,给编辑器看的
+		/// </summary>
+		public bool IsFold { get; set; }
+	}
+}

+ 43 - 0
CSharp/App/Modules/Tree/TreeNodeDataArray.cs

@@ -0,0 +1,43 @@
+using System.Collections.Generic;
+using System.Runtime.Serialization;
+
+namespace Tree
+{
+	[DataContract]
+	public class TreeNodeDataArray
+	{
+		private readonly List<TreeNodeData> treeNodeDatas = new List<TreeNodeData>();
+
+		[DataMember(Order = 1)]
+		public List<TreeNodeData> TreeNodeDatas
+		{
+			get
+			{
+				return this.treeNodeDatas;
+			}
+		}
+
+		private readonly Dictionary<int, TreeNodeData> treeNodeDict = new Dictionary<int, TreeNodeData>();
+
+		public void Init()
+		{
+			foreach (TreeNodeData nodeData in this.treeNodeDatas)
+			{
+				treeNodeDict[nodeData.Id] = nodeData;
+			}
+		}
+
+		public void Add(TreeNodeData treeNodeData)
+		{
+			this.treeNodeDatas.Add(treeNodeData);
+		}
+
+		public TreeNodeData this[int id]
+		{
+			get
+			{
+				return this.treeNodeDict[id];
+			}
+		}
+	}
+}

+ 72 - 43
CSharp/App/Modules/Tree/TreeNodeViewModel.cs

@@ -1,6 +1,5 @@
 using System;
 using System.Collections.ObjectModel;
-using System.Windows;
 using Microsoft.Practices.Prism.Mvvm;
 
 namespace Tree
@@ -8,10 +7,11 @@ namespace Tree
 	public class TreeNodeViewModel : BindableBase
 	{
 		private static int globalNum;
-		private readonly int num;
 		private static double width = 80;
-		private static double height = 50;
-		private readonly TreeNode treeNode;
+		private static double height = 50;
+		private double x;
+		private double y;
+		private readonly TreeNodeData treeNodeData;
 		private double connectorX2;
 		private double connectorY2;
 		private double prelim;
@@ -19,43 +19,72 @@ namespace Tree
 		private double ancestorModify;
 		private TreeNodeViewModel parent;
 
-		private ObservableCollection<TreeNodeViewModel> children = new ObservableCollection<TreeNodeViewModel>();
+		private ObservableCollection<TreeNodeViewModel> children = new ObservableCollection<TreeNodeViewModel>();
+
+		/// <summary>
+		/// 用于初始化根节点
+		/// </summary>
+		/// <param name="x"></param>
+		/// <param name="y"></param>
+		public TreeNodeViewModel(double x, double y)
+		{
+			this.x = x;
+			this.y = y;
+			this.treeNodeData = new TreeNodeData();
+			this.treeNodeData.Id = globalNum++;
+			this.parent = parent ?? this;
+			this.connectorX2 = 0;
+			this.connectorY2 = Height / 2;
+		}
 
-		public TreeNodeViewModel(TreeNode treeNode, TreeNodeViewModel parent)
-		{
-			this.num = globalNum++;
-			this.treeNode = treeNode;
+		public TreeNodeViewModel(TreeNodeViewModel parent)
+		{
+			this.treeNodeData = new TreeNodeData();
+			this.treeNodeData.Id = globalNum++;
 			this.parent = parent ?? this;
-			if (this.parent == this)
-			{
-				this.connectorX2 = 0;
-				this.connectorY2 = Height / 2;
-			}
-			else
-			{
-				this.connectorX2 = Width + this.Parent.X - this.X;
-				this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
-			}
-		}
 
-		public int Num
-		{
-			get
-			{
-				return this.num;
-			}
+			this.connectorX2 = Width + this.Parent.X - this.X;
+			this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
+		}
+
+		public TreeNodeViewModel(TreeNodeData data, TreeNodeViewModel parent)
+		{
+			this.treeNodeData = data;
+			this.parent = parent ?? this;
+			if (this.parent == this)
+			{
+				this.x = 200;
+				this.y = 10;
+				this.connectorX2 = 0;
+				this.connectorY2 = Height / 2;
+			}
+			else
+			{
+				this.connectorX2 = Width + this.Parent.X - this.X;
+				this.connectorY2 = Height / 2 + this.Parent.Y - this.Y;
+			}
 		}
 
-		public int ParentNum
+		public TreeNodeData TreeNodeData
 		{
 			get
 			{
-				if (this.parent == null)
+				this.treeNodeData.ChildrenId.Clear();
+				foreach (TreeNodeViewModel child in children)
 				{
-					return -1;
+					this.treeNodeData.ChildrenId.Add(child.Id);
 				}
-				return this.parent.Num;
+				this.treeNodeData.ParentId = this.IsRoot? 0 : this.Parent.Id;
+				return this.treeNodeData;
 			}
+		}
+
+		public int Id
+		{
+			get
+			{
+				return this.treeNodeData.Id;
+			}
 		}
 
 		public static double Width
@@ -118,22 +147,22 @@ namespace Tree
 		{
 			get
 			{
-				return this.treeNode.X;
+				return this.x;
 			}
 			set
 			{
-				if (Math.Abs(this.treeNode.X - value) < 0.1)
+				if (Math.Abs(this.x - value) < 0.1)
 				{
 					return;
 				}
-				this.treeNode.X = value;
+				this.x = value;
 				this.OnPropertyChanged("X");
 
 				this.ConnectorX2 = Width / 2 + this.Parent.X - this.X;
 
 				foreach (TreeNodeViewModel child in this.Children)
 				{
-					child.ConnectorX2 = Width / 2 + this.treeNode.X - child.X;
+					child.ConnectorX2 = Width / 2 + this.X - child.X;
 				}
 			}
 		}
@@ -142,23 +171,23 @@ namespace Tree
 		{
 			get
 			{
-				return this.treeNode.Y;
+				return this.y;
 			}
 			set
 			{
-				if (Math.Abs(this.treeNode.Y - value) < 0.1)
+				if (Math.Abs(this.Y - value) < 0.1)
 				{
 					return;
 				}
 
-				this.treeNode.Y = value;
+				this.y = value;
 				this.OnPropertyChanged("Y");
 
 				this.ConnectorY2 = Height + this.Parent.Y - this.Y;
 
 				foreach (var child in this.Children)
 				{
-					child.ConnectorY2 = Height + this.treeNode.Y - child.Y;
+					child.ConnectorY2 = Height + this.Y - child.Y;
 				}
 			}
 		}
@@ -207,17 +236,17 @@ namespace Tree
 		{
 			get
 			{
-				return this.treeNode.Type;
+				return this.treeNodeData.Type;
 			}
 			set
 			{
-				if (this.treeNode.Type == value)
+				if (this.treeNodeData.Type == value)
 				{
 					return;
 				}
 				int type = 0;
 				this.SetProperty(ref type, value);
-				this.treeNode.Type = value;
+				this.treeNodeData.Type = value;
 			}
 		}
 
@@ -241,11 +270,11 @@ namespace Tree
 		{
 			get
 			{
-				return treeNode.IsFold;
+				return this.treeNodeData.IsFold;
 			}
 			set
 			{
-				treeNode.IsFold = value;
+				this.treeNodeData.IsFold = value;
 			}
 		}