Commit 464d78be by liulongfei

添加项目管理

parent e5e6632b
......@@ -77,6 +77,14 @@
<Reference Include="PresentationFramework" />
</ItemGroup>
<ItemGroup>
<Page Include="Widgets\InputControl\TextInputControl\TextInputWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Widgets\InputControl\TextInputControl\TextInputControl.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="Themes\Generic.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
......@@ -98,8 +106,17 @@
<DependentUpon>Settings.settings</DependentUpon>
<DesignTimeSharedInput>True</DesignTimeSharedInput>
</Compile>
<Compile Include="Widgets\InputControl\TextInputControl\TextInputWindow.xaml.cs">
<DependentUpon>TextInputWindow.xaml</DependentUpon>
</Compile>
<Compile Include="Widgets\InputControl\TextInputControl\TextInputControl.xaml.cs">
<DependentUpon>TextInputControl.xaml</DependentUpon>
</Compile>
<Compile Include="Widgets\GridColumnEx\GridColumnResizeMinHeight.cs" />
<Compile Include="Widgets\InputControl\TextInputControl\TextInputControlModel.cs" />
<Compile Include="Widgets\InputControl\TextInputControl\TextInputWindowModel.cs" />
<Compile Include="Widgets\LeftRightTextEdit\LeftRightTextEdit.cs" />
<Compile Include="Widgets\TreeViewControl\DefaultTreeListNodeImageSelector.cs" />
<EmbeddedResource Include="Properties\Resources.resx">
<Generator>ResXFileCodeGenerator</Generator>
<LastGenOutput>Resources.Designer.cs</LastGenOutput>
......
<UserControl x:Class="VIZ.Package.Common.TextInputControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:dxi="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
xmlns:common="clr-namespace:VIZ.Package.Common;assembly=VIZ.Package.Common"
xmlns:local="clr-namespace:VIZ.Package.Common"
d:DataContext="{d:DesignInstance Type=local:TextInputControlModel}"
mc:Ignorable="d" d:Background="White"
d:DesignHeight="40" d:DesignWidth="600">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBlock Text="{Binding Path=Label}" VerticalAlignment="Center" Margin="20,0,20,0"></TextBlock>
<dxe:TextEdit Grid.Column="1" Height="30" Text="{Binding Path=Text,Mode=TwoWay}"></dxe:TextEdit>
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace VIZ.Package.Common
{
/// <summary>
/// TextInputControl.xaml 的交互逻辑
/// </summary>
public partial class TextInputControl : UserControl
{
public TextInputControl()
{
InitializeComponent();
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
namespace VIZ.Package.Common
{
/// <summary>
/// 文本输入控件模型
/// </summary>
public class TextInputControlModel : ViewModelBase
{
// ==========================================================================
// Property
// ==========================================================================
#region Label -- 标签
private string label;
/// <summary>
/// 标签
/// </summary>
public string Label
{
get { return label; }
set { label = value; this.RaisePropertyChanged(nameof(Label)); }
}
#endregion
#region Text -- 文本
private string text;
/// <summary>
/// 文本
/// </summary>
public string Text
{
get { return text; }
set { text = value; this.RaisePropertyChanged(nameof(Text)); }
}
#endregion
// ==========================================================================
// Command
// ==========================================================================
// ==========================================================================
// Protected Function
// ==========================================================================
}
}
<dx:ThemedWindow x:Class="VIZ.Package.Common.TextInputWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:local="clr-namespace:VIZ.Package.Common"
mc:Ignorable="d"
WindowStyle="None" WindowStartupLocation="CenterScreen"
d:DataContext="{d:DesignInstance Type=local:TextInputWindowModel}"
d:Background="White"
Title="TextInputWindow" Height="140" Width="500">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<local:TextInputControl Margin="20,10,30,0"></local:TextInputControl>
<!-- 按钮组 -->
<StackPanel Grid.Row="1" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Content="确定" Height="30" Width="80"
Command="{Binding Path=EnterCommand}"></Button>
<Button Content="取消" Height="30" Width="80" Margin="20,0,30,0"
Command="{Binding Path=CancelCommand}"></Button>
</StackPanel>
</Grid>
</dx:ThemedWindow>
using DevExpress.Xpf.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using VIZ.Framework.Core;
namespace VIZ.Package.Common
{
/// <summary>
/// Interaction logic for TextInputWindow.xaml
/// </summary>
public partial class TextInputWindow : ThemedWindow
{
public TextInputWindow()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new TextInputWindowModel());
}
}
}
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VIZ.Framework.Core;
namespace VIZ.Package.Common
{
/// <summary>
/// 文本输入窗口模型
/// </summary>
public class TextInputWindowModel : TextInputControlModel
{
public TextInputWindowModel()
{
// 初始化命令
this.InitCommand();
}
/// <summary>
/// 初始化命令
/// </summary>
private void InitCommand()
{
this.EnterCommand = new VCommand(this.Enter);
this.CancelCommand = new VCommand(this.Cancel);
}
// ==========================================================================
// Command
// ==========================================================================
#region EnterCommand -- 确定命令
/// <summary>
/// 确定命令
/// </summary>
public VCommand EnterCommand { get; set; }
/// <summary>
/// 确定
/// </summary>
private void Enter()
{
Window window = this.GetWindow();
if (window == null)
return;
window.DialogResult = true;
window.Close();
}
#endregion
#region CancelCommand -- 取消命令
/// <summary>
/// 取消命令
/// </summary>
public VCommand CancelCommand { get; set; }
/// <summary>
/// 取消
/// </summary>
private void Cancel()
{
Window window = this.GetWindow();
if (window == null)
return;
window.DialogResult = false;
window.Close();
}
#endregion
}
}
using DevExpress.Xpf.Grid.TreeList;
using DevExpress.Xpf.Grid;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Package.Domain;
using System.Windows.Media;
namespace VIZ.Package.Common
{
/// <summary>
/// 默认树节点图片选择器
/// </summary>
public class DefaultTreeListNodeImageSelector : TreeListNodeImageSelector
{
/// <summary>
/// 图标
/// </summary>
public ImageSource Icon { get; set; }
/// <summary>
/// 选择图标
/// </summary>
/// <param name="rowData">行数据</param>
/// <returns>图标</returns>
public override ImageSource Select(TreeListRowData rowData)
{
return Icon;
}
}
}
......@@ -18,6 +18,21 @@ namespace VIZ.Package.Domain
public const string APPLICATION_GROUP_NAME = "APPLICATION_GROUP";
/// <summary>
/// 项目文件扩展名
/// </summary>
public const string PROJECT_FILE_EXTENSION = ".viz_pkg";
/// <summary>
/// 项目日志文件后缀
/// </summary>
public const string PROJECT_FILE_LOG_NAME_SUFFIX = "-log.viz_pkg";
/// <summary>
/// 项目文件过滤器
/// </summary>
public const string PROJECT_FILE_FILTER = "viz_pkg files(*.viz_pkg)|*.viz_pkg";
/// <summary>
/// Viz 层集合
/// </summary>
public readonly static List<VizLayer> VIZ_LAYERS = new List<VizLayer> { VizLayer.FRONT_LAYER, VizLayer.MAIN_LAYER, VizLayer.BACK_LAYER };
......
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
namespace VIZ.Package.Domain
{
/// <summary>
/// 文件模型
/// </summary>
public class FileModel : ModelBase
{
/// <summary>
/// 文件模型
/// </summary>
/// <param name="path">文件路径</param>
public FileModel(string path)
{
this.Path = path;
this.Name = System.IO.Path.GetFileName(path);
this.Extension = System.IO.Path.GetExtension(path);
}
#region Name -- 名称
private string name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; this.RaisePropertyChanged(nameof(Name)); }
}
#endregion
#region Path -- 路径
private string path;
/// <summary>
/// 路径
/// </summary>
public string Path
{
get { return path; }
set { path = value; this.RaisePropertyChanged(nameof(Path)); }
}
#endregion
#region Extension -- 文件扩展名
private string extension;
/// <summary>
/// 文件扩展名
/// </summary>
public string Extension
{
get { return extension; }
set { extension = value; this.RaisePropertyChanged(nameof(Extension)); }
}
#endregion
#region Parent -- 父级节点
private FolderModel parent;
/// <summary>
/// 父级节点
/// </summary>
public FolderModel Parent
{
get { return parent; }
set { parent = value; this.RaisePropertyChanged(nameof(Parent)); }
}
#endregion
}
}
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Framework.Core;
namespace VIZ.Package.Domain
{
/// <summary>
/// 文件夹模型
/// </summary>
public class FolderModel : ModelBase
{
/// <summary>
/// 文件夹模型
/// </summary>
/// <param name="path">文件夹路径</param>
public FolderModel(string path)
{
this.Path = path;
this.Name = System.IO.Path.GetFileName(path);
}
#region Name -- 名称
private string name;
/// <summary>
/// 名称
/// </summary>
public string Name
{
get { return name; }
set { name = value; this.RaisePropertyChanged(nameof(Name)); }
}
#endregion
#region Path -- 路径
private string path;
/// <summary>
/// 路径
/// </summary>
public string Path
{
get { return path; }
set { path = value; this.RaisePropertyChanged(nameof(Path)); }
}
#endregion
#region Parent -- 父级节点
private FolderModel parent;
/// <summary>
/// 父级节点
/// </summary>
public FolderModel Parent
{
get { return parent; }
set { parent = value; this.RaisePropertyChanged(nameof(Parent)); }
}
#endregion
#region Folders -- 子文件夹集合
private ObservableCollection<FolderModel> folders = new ObservableCollection<FolderModel>();
/// <summary>
/// 子文件夹集合
/// </summary>
public ObservableCollection<FolderModel> Folders
{
get { return folders; }
set { folders = value; this.RaisePropertyChanged(nameof(Folders)); }
}
#endregion
#region Files -- 文件集合
private ObservableCollection<FileModel> files = new ObservableCollection<FileModel>();
/// <summary>
/// 文件集合
/// </summary>
public ObservableCollection<FileModel> Files
{
get { return files; }
set { files = value; this.RaisePropertyChanged(nameof(Files)); }
}
#endregion
// -----------------------------------------------
// 扩展属性
#region IsLoadedFolder -- 是否已经完成了文件夹的加载
private bool isLoadedFolder;
/// <summary>
/// 是否已经完成了文件夹的加载
/// </summary>
public bool IsLoadedFolder
{
get { return isLoadedFolder; }
set { isLoadedFolder = value; this.RaisePropertyChanged(nameof(IsLoadedFolder)); }
}
#endregion
#region IsLoadedFiles -- 是否已经完成了文件的加载
private bool isLoadedFiles;
/// <summary>
/// 是否已经完成了文件的加载
/// </summary>
public bool IsLoadedFiles
{
get { return isLoadedFiles; }
set { isLoadedFiles = value; this.RaisePropertyChanged(nameof(IsLoadedFiles)); }
}
#endregion
#region IsExpand -- 文件夹是否被展开
private bool isExpand;
/// <summary>
/// 文件夹是否被展开
/// </summary>
public bool IsExpand
{
get { return isExpand; }
set { isExpand = value; this.RaisePropertyChanged(nameof(IsExpand)); }
}
#endregion
}
}
......@@ -100,6 +100,8 @@
<Compile Include="Core\IPackageEndpointManager.cs" />
<Compile Include="Model\ControlObject\ControlFieldNodeModel.cs" />
<Compile Include="Model\ControlObject\ControlObjectModel.cs" />
<Compile Include="Model\File\FileModel.cs" />
<Compile Include="Model\File\FolderModel.cs" />
<Compile Include="Model\Page\PageGroupModel.cs" />
<Compile Include="Model\Page\PageModel.cs" />
<Compile Include="Model\Page\PageModelBase.cs" />
......
......@@ -252,5 +252,8 @@
<ItemGroup>
<Resource Include="Icons\preview_refresh_32x32.png" />
</ItemGroup>
<ItemGroup>
<Resource Include="Icons\file_32x32.png" />
</ItemGroup>
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
</Project>
\ No newline at end of file
......@@ -38,5 +38,10 @@
<Button Content="错误日志" Command="{Binding ErrorLogCommand}"></Button>
</StackPanel>
</GroupBox>
<GroupBox Header="功能测试" Grid.Column="2">
<StackPanel>
<Button Content="项目面板" Command="{Binding ProjectPanelCommand}"></Button>
</StackPanel>
</GroupBox>
</Grid>
</dx:ThemedWindow>
......@@ -36,6 +36,9 @@ namespace VIZ.Package.Module
// Log
this.ErrorLogCommand = new VCommand(this.ErrorLog);
// Project
this.ProjectPanelCommand = new VCommand(this.ProjectPanel);
}
// ======================================================================
......@@ -106,5 +109,26 @@ namespace VIZ.Package.Module
}
#endregion
// ---------------------------------------------------------
// Project
#region ProjectPanelCommand -- 项目面板命令
/// <summary>
/// 项目面板命令
/// </summary>
public VCommand ProjectPanelCommand { get; set; }
/// <summary>
/// 项目面板
/// </summary>
private void ProjectPanel()
{
OpenProjectWindow window = new OpenProjectWindow();
window.Show();
}
#endregion
}
}
......@@ -21,8 +21,6 @@ namespace VIZ.Package.Module
{
// 初始化命令
this.InitCommand();
}
/// <summary>
......
......@@ -163,13 +163,23 @@ namespace VIZ.Package.Module
}
// 创建项目文件
SaveFileDialog sfd = new SaveFileDialog();
sfd.Filter = "viz_pkg files(*.viz_pkg)|*.viz_pkg";
if (sfd.ShowDialog() != DialogResult.OK)
SaveProjectWindow window = new SaveProjectWindow();
window.ShowDialog();
if (window.DialogResult != true)
return;
this.ProjectName = System.IO.Path.GetFileNameWithoutExtension(sfd.FileName);
ApplicationDomainEx.ProjectDbContext = new ProjectDbContext(sfd.FileName);
SaveProjectWindowModel vm = window.DataContext as SaveProjectWindowModel;
if (vm == null)
return;
string path = System.IO.Path.Combine(vm.SelectedFolderModel.Path, vm.ProjectName);
if (System.IO.File.Exists(path))
{
System.IO.File.Delete(path);
}
this.ProjectName = System.IO.Path.GetFileNameWithoutExtension(path);
ApplicationDomainEx.ProjectDbContext = new ProjectDbContext(path);
// 为项目添加默认页分组
PageGroupEntity defaultGroup = new PageGroupEntity();
......@@ -178,7 +188,7 @@ namespace VIZ.Package.Module
ApplicationDomainEx.ProjectDbContext.PageGroup.Insert(defaultGroup);
// 保存当前项目的完整路径
ApplicationDomainEx.VizConfig.ProjectPath = sfd.FileName;
ApplicationDomainEx.VizConfig.ProjectPath = path;
ApplicationDomainEx.LocalDbContext.VizConfig.Update(ApplicationDomainEx.VizConfig);
// 发送项目打开消息
......@@ -214,14 +224,17 @@ namespace VIZ.Package.Module
ApplicationDomainEx.ProjectDbContext.Dispose();
}
OpenFileDialog ofd = new OpenFileDialog();
ofd.Filter = "viz_pkg files(*.viz_pkg)|*.viz_pkg";
ofd.Multiselect = false;
if (ofd.ShowDialog() != DialogResult.OK)
OpenProjectWindow window = new OpenProjectWindow();
window.ShowDialog();
if (window.DialogResult != true)
return;
OpenProjectWindowModel vm = window.DataContext as OpenProjectWindowModel;
if (vm == null)
return;
string path = ofd.FileName;
this.OpenProject(path);
this.OpenProject(vm.SelectedFileModel.Path);
}
/// <summary>
......
<dx:ThemedWindow x:Class="VIZ.Package.Module.OpenProjectWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
xmlns:fcommon="clr-namespace:VIZ.Framework.Common;assembly=VIZ.Framework.Common"
xmlns:domain="clr-namespace:VIZ.Package.Domain;assembly=VIZ.Package.Domain"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VIZ.Package.Module"
d:DataContext="{d:DesignInstance Type=local:OpenProjectWindowModel}"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="项目管理" Height="600" Width="800">
<Grid Margin="0,10,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<local:ProjectTreePanel x:Name="projectTreePanel">
<local:ProjectTreePanel.FolderContextMenu>
<ContextMenu>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Opened" Command="{Binding Path=PlacementTarget.DataContext.FolderContentMenuOpendCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<MenuItem Header="新建" Command="{Binding Path=PlacementTarget.DataContext.CreateFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
<MenuItem Header="删除" Command="{Binding Path=PlacementTarget.DataContext.DeleteFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
<Separator/>
<MenuItem Header="刷新" Command="{Binding Path=PlacementTarget.DataContext.RefreshFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
</ContextMenu>
</local:ProjectTreePanel.FolderContextMenu>
<local:ProjectTreePanel.FileContextMenu>
<ContextMenu>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Opened" Command="{Binding Path=PlacementTarget.DataContext.FileContentMenuOpendCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<MenuItem Header="删除" Command="{Binding Path=PlacementTarget.DataContext.DeleteFileCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
<Separator/>
<MenuItem Header="刷新" Command="{Binding Path=PlacementTarget.DataContext.RefreshFileCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
</ContextMenu>
</local:ProjectTreePanel.FileContextMenu>
</local:ProjectTreePanel>
<!-- 按钮组 -->
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1" Grid.ColumnSpan="2">
<Button Width="80" Height="40" Content="打开项目" Margin="20,0,20,0" Command="{Binding Path=OpenProjectCommand}"></Button>
</StackPanel>
</Grid>
</dx:ThemedWindow>
\ No newline at end of file
......@@ -11,18 +11,20 @@ using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using VIZ.Framework.Core;
namespace VIZ.Package.Module
{
/// <summary>
/// Interaction logic for ProjectManagerWindow.xaml
/// Interaction logic for OpenProjectWindow.xaml
/// </summary>
public partial class ProjectManagerWindow : ThemedWindow
public partial class OpenProjectWindow : ThemedWindow
{
public ProjectManagerWindow()
public OpenProjectWindow()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new OpenProjectWindowModel());
}
}
}
<dx:ThemedWindow x:Class="VIZ.Package.Module.ProjectManagerWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
xmlns:fcommon="clr-namespace:VIZ.Framework.Common;assembly=VIZ.Framework.Common"
xmlns:domain="clr-namespace:VIZ.Package.Domain;assembly=VIZ.Package.Domain"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VIZ.Package.Module"
d:DataContext="{d:DesignInstance Type=local:ProjectManagerWindowModel}"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="项目管理" Height="800" Width="1400">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding Path=LoadedCommand}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<Grid>
<!-- 項目树 -->
<dxg:TreeViewControl ItemsSource="{Binding Path=FolderModels}" Margin="0,0,5,0"
SelectedItem="{Binding Path=SelectedFolderModel,Mode=TwoWay}"
ContextMenu="{Binding Path=FolderContextMenu,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:GHResourcePanel}}}"
SelectionMode="Row"
ShowNodeImages="True" ShowSearchPanel="False"
ExpandStateFieldName="IsExpand"
AllowEditing="False" TreeViewFieldName="Name" ChildNodesPath="Children">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="NodeDoubleClick" PassEventArgsToCommand="True" Command="{Binding Path=FolderExpandCommand}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<dxg:TreeViewControl.NodeImageSelector>
<local:GHResourceFolderNodeImageSelector Folder="/VIZ.Package.Module.Resource;component/Icons/folder_24x24.png"
Project="/VIZ.Package.Module.Resource;component/Icons/project_24x24.png"></local:GHResourceFolderNodeImageSelector>
</dxg:TreeViewControl.NodeImageSelector>
</dxg:TreeViewControl>
<!-- 文件等待 -->
<dx:WaitIndicator DeferedVisibility="{Binding IsFileLoading}" Content="Loading..." Grid.Column="1" Grid.Row="1" />
</Grid>
</dx:ThemedWindow>
\ No newline at end of file
<UserControl x:Class="VIZ.Package.Module.ProjectTreePanel"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:dxi="http://schemas.devexpress.com/winfx/2008/xaml/core/internal"
xmlns:dxgt="http://schemas.devexpress.com/winfx/2008/xaml/grid/themekeys"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
xmlns:common="clr-namespace:VIZ.Package.Common;assembly=VIZ.Package.Common"
xmlns:local="clr-namespace:VIZ.Package.Module"
xmlns:domain="clr-namespace:VIZ.Package.Domain;assembly=VIZ.Package.Domain"
xmlns:resource="clr-namespace:VIZ.Package.Module.Resource;assembly=VIZ.Package.Module.Resource"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance Type=local:ProjectTreePanelModel}"
d:DesignHeight="450" d:DesignWidth="800">
<UserControl.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="/VIZ.Package.Module.Resource;component/DevExpreess/GridControl/GridControl_Files.xaml"></ResourceDictionary>
<ResourceDictionary Source="/VIZ.Framework.Common.Resource;component/Style/GridSplitter/GridSplitter_None.xaml"></ResourceDictionary>
<ResourceDictionary Source="/VIZ.Package.Module.Resource;component/Style/CheckBox/CheckBox_Resource.xaml"></ResourceDictionary>
</ResourceDictionary.MergedDictionaries>
<fcore:Bitmap2ImageSourceConverter x:Key="Bitmap2ImageSourceConverter"></fcore:Bitmap2ImageSourceConverter>
</ResourceDictionary>
</UserControl.Resources>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Loaded" Command="{Binding Path=LoadedCommand}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="300" MinWidth="300" MaxWidth="500"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<!-- 文件夹 -->
<dxg:TreeViewControl ItemsSource="{Binding Path=FolderModels}" Margin="0,0,5,0"
SelectedItem="{Binding Path=SelectedFolderModel,Mode=TwoWay}"
ContextMenu="{Binding Path=FolderContextMenu,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProjectTreePanel}}}"
SelectionMode="Row" ShowExpandButtons="True" x:Name="t1"
ShowNodeImages="True" ShowSearchPanel="False"
ExpandStateFieldName="IsExpand"
AllowEditing="False" TreeViewFieldName="Name" ChildNodesPath="Folders">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="NodeExpanding" PassEventArgsToCommand="True" Command="{Binding Path=FolderExpandingCommand}"></dxmvvm:EventToCommand>
<dxmvvm:EventToCommand EventName="NodeDoubleClick" PassEventArgsToCommand="True" Command="{Binding Path=FolderExpandCommand}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<dxg:TreeViewControl.NodeImageSelector>
<common:DefaultTreeListNodeImageSelector Icon="/VIZ.Package.Module.Resource;component/Icons/folder_24x24.png"></common:DefaultTreeListNodeImageSelector>
</dxg:TreeViewControl.NodeImageSelector>
<dxg:TreeViewControl.NodeContentStyle>
<Style TargetType="dxg:LightweightCellEditor">
<Setter Property="Height" Value="30"></Setter>
</Style>
</dxg:TreeViewControl.NodeContentStyle>
</dxg:TreeViewControl>
<!-- 文件夹等待 -->
<dx:WaitIndicator DeferedVisibility="{Binding IsFolderLoading}" Content="Loading..." Margin="0,0,6,0" />
<GridSplitter HorizontalAlignment="Right" Width="5" Style="{StaticResource GridSplitter_None}"></GridSplitter>
<!-- 文件列表 -->
<dxg:GridControl ItemsSource="{Binding FileModels}" ShowBorder="False"
IsEnabled="{Binding Path=IsFilePanelEnabled}"
IsFilterEnabled="False" Grid.Column="1" SelectionMode="Row"
SelectedItem="{Binding SelectedFileModel,Mode=TwoWay}"
SelectedItems="{Binding SelectedFileModels,Mode=OneWayToSource}"
ContextMenu="{Binding Path=FileContextMenu,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type local:ProjectTreePanel}}}">
<dxg:GridControl.Columns>
<dxg:GridColumn Header="名称" FieldName="Name" ReadOnly="True" AllowSorting="False" AllowColumnFiltering="False"
Width="400">
<dxg:GridColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="40"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Image Width="20" Height="20"
Source="/VIZ.Package.Module.Resource;component/Icons/file_32x32.png"></Image>
<TextBlock Text="{Binding Path=Row.Name}" VerticalAlignment="Center" Grid.Column="1"></TextBlock>
</Grid>
</DataTemplate>
</dxg:GridColumn.CellTemplate>
</dxg:GridColumn>
</dxg:GridControl.Columns>
<dxg:GridControl.View>
<dxg:TableView IsColumnMenuEnabled="False"
AllowEditing="True" ShowIndicator="False" RowMinHeight="30"
NavigationStyle="Row" ShowVerticalLines="False" ShowHorizontalLines="False"
ShowGroupPanel="False" EditorShowMode="MouseDown"
AllowDragDrop="True" ShowColumnHeaders="False"
ShowBandsPanel="False"
ShowTotalSummary="False"
ShowFixedTotalSummary="False"
ShowDragDropHint="False"
ShowTargetInfoInDragDropHint="false">
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="RowDoubleClick" Command="{Binding Path=FileDoubleClickCommand}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
</dxg:TableView>
</dxg:GridControl.View>
</dxg:GridControl>
<!-- 文件等待 -->
<dx:WaitIndicator DeferedVisibility="{Binding IsFileLoading}" Content="Loading..." Grid.Column="1" Grid.Row="1" />
</Grid>
</UserControl>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;
namespace VIZ.Package.Module
{
/// <summary>
/// ProjectTreePanel.xaml 的交互逻辑
/// </summary>
public partial class ProjectTreePanel : UserControl
{
public ProjectTreePanel()
{
InitializeComponent();
}
#region FolderContextMenu -- 文件夹右键菜单
/// <summary>
/// 文件夹右键菜单
/// </summary>
public ContextMenu FolderContextMenu
{
get { return (ContextMenu)GetValue(FolderContextMenuProperty); }
set { SetValue(FolderContextMenuProperty, value); }
}
/// <summary>
/// Using a DependencyProperty as the backing store for FolderContextMenu. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty FolderContextMenuProperty =
DependencyProperty.Register("FolderContextMenu", typeof(ContextMenu), typeof(ProjectTreePanel), new PropertyMetadata(null));
#endregion
#region FileContextMenu -- 文件右键菜单
/// <summary>
/// 文件右键菜单
/// </summary>
public ContextMenu FileContextMenu
{
get { return (ContextMenu)GetValue(FileContextMenuProperty); }
set { SetValue(FileContextMenuProperty, value); }
}
/// <summary>
/// Using a DependencyProperty as the backing store for FileContextMenu. This enables animation, styling, binding, etc...
/// </summary>
public static readonly DependencyProperty FileContextMenuProperty =
DependencyProperty.Register("FileContextMenu", typeof(ContextMenu), typeof(ProjectTreePanel), new PropertyMetadata(null));
#endregion
}
}
<dx:ThemedWindow x:Class="VIZ.Package.Module.SaveProjectWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
xmlns:fcore="clr-namespace:VIZ.Framework.Core;assembly=VIZ.Framework.Core"
xmlns:fcommon="clr-namespace:VIZ.Framework.Common;assembly=VIZ.Framework.Common"
xmlns:domain="clr-namespace:VIZ.Package.Domain;assembly=VIZ.Package.Domain"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:local="clr-namespace:VIZ.Package.Module"
d:DataContext="{d:DesignInstance Type=local:SaveProjectWindowModel}"
mc:Ignorable="d" WindowStartupLocation="CenterScreen"
Title="项目管理" Height="600" Width="800">
<Grid Margin="0,10,0,0">
<Grid.RowDefinitions>
<RowDefinition Height="*"></RowDefinition>
<RowDefinition Height="60"></RowDefinition>
</Grid.RowDefinitions>
<local:ProjectTreePanel x:Name="projectTreePanel">
<local:ProjectTreePanel.FolderContextMenu>
<ContextMenu>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Opened" Command="{Binding Path=PlacementTarget.DataContext.FolderContentMenuOpendCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<MenuItem Header="新建" Command="{Binding Path=PlacementTarget.DataContext.CreateFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"/>
<MenuItem Header="删除" Command="{Binding Path=PlacementTarget.DataContext.DeleteFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
<Separator/>
<MenuItem Header="刷新" Command="{Binding Path=PlacementTarget.DataContext.RefreshFolderCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
</ContextMenu>
</local:ProjectTreePanel.FolderContextMenu>
<local:ProjectTreePanel.FileContextMenu>
<ContextMenu>
<dxmvvm:Interaction.Behaviors>
<dxmvvm:EventToCommand EventName="Opened" Command="{Binding Path=PlacementTarget.DataContext.FileContentMenuOpendCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></dxmvvm:EventToCommand>
</dxmvvm:Interaction.Behaviors>
<MenuItem Header="删除" Command="{Binding Path=PlacementTarget.DataContext.DeleteFileCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
<Separator/>
<MenuItem Header="刷新" Command="{Binding Path=PlacementTarget.DataContext.RefreshFileCommand, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=ContextMenu}}"></MenuItem>
</ContextMenu>
</local:ProjectTreePanel.FileContextMenu>
</local:ProjectTreePanel>
<!-- 按钮组 -->
<Grid Grid.Row="1">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="2*"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="1" VerticalAlignment="Center">
<TextBlock Text="项目名:" Margin="20,0,0,0" VerticalAlignment="Center"></TextBlock>
<dxe:TextEdit Width="400" Margin="20,0,0,0" EditValue="{Binding Path=ProjectName,Mode=TwoWay}"></dxe:TextEdit>
</StackPanel>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Right" Grid.Row="1" Grid.Column="1">
<Button Width="80" Height="40" Content="保存项目" Margin="20,0,20,0" Command="{Binding Path=SaveProjectCommand}"></Button>
</StackPanel>
</Grid>
</Grid>
</dx:ThemedWindow>
\ No newline at end of file
using DevExpress.Xpf.Core;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
using VIZ.Framework.Core;
namespace VIZ.Package.Module
{
/// <summary>
/// Interaction logic for SaveProjectWindow.xaml
/// </summary>
public partial class SaveProjectWindow : ThemedWindow
{
public SaveProjectWindow()
{
InitializeComponent();
WPFHelper.BindingViewModel(this, new SaveProjectWindowModel());
}
}
}
using DevExpress.Xpf.Core;
using DevExpress.Utils.Html;
using DevExpress.Xpf.Core;
using log4net;
using System;
using System.Collections.Generic;
......@@ -7,22 +8,24 @@ using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Media.Animation;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;
namespace VIZ.Package.Module
{
/// <summary>
/// 项目管理窗口模型
/// 打开项目窗口模型
/// </summary>
public class ProjectManagerWindowModel : ViewModelBase
public class OpenProjectWindowModel : ProjectTreePanelModel
{
/// <summary>
/// 日志
/// </summary>
private readonly static ILog log = LogManager.GetLogger(typeof(ProjectManagerWindowModel));
private readonly static ILog log = LogManager.GetLogger(typeof(OpenProjectWindowModel));
public ProjectManagerWindowModel()
public OpenProjectWindowModel()
{
// 初始化命令
this.InitCommand();
......@@ -33,35 +36,65 @@ namespace VIZ.Package.Module
/// </summary>
private void InitCommand()
{
this.LoadedCommand = new VCommand(this.Loaded);
this.OpenProjectCommand = new VCommand(this.OpenProject);
}
// ==========================================================================
// Property
// Config
// ==========================================================================
// ==========================================================================
// Controller & Service
// ==========================================================================
// ==========================================================================
// Property
// ==========================================================================
// ==========================================================================
// Command
// ==========================================================================
#region LoadedCommand -- 加载命令
#region OpenProjectCommand -- 打开项目命令
/// <summary>
/// 加载命令
/// 打开项目命令
/// </summary>
public VCommand LoadedCommand { get; set; }
public VCommand OpenProjectCommand { get; set; }
/// <summary>
/// 加载
/// 打开项目命令
/// </summary>
private void Loaded()
private void OpenProject()
{
if (this.SelectedFileModel == null)
{
DXMessageBox.Show("请选择项目文件");
return;
}
Window window = this.GetWindow();
if (window == null)
return;
window.DialogResult = true;
window.Close();
}
#endregion
// ==========================================================================
// Protected Function
// ==========================================================================
/// <summary>
/// 文件双击命令
/// </summary>
protected override void OnFileDoubleClick()
{
this.OpenProject();
}
}
}
\ No newline at end of file
using DevExpress.Data.Helpers;
using DevExpress.Xpf.Core;
using log4net;
using System;
using System.Collections;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Controls;
using System.Windows.Media.Animation;
using VIZ.Framework.Core;
using VIZ.Package.Common;
using VIZ.Package.Domain;
using VIZ.Package.Service;
namespace VIZ.Package.Module
{
/// <summary>
/// 项目树面板模型
/// </summary>
public class ProjectTreePanelModel : ViewModelBase
{
/// <summary>
/// 日志
/// </summary>
private readonly static ILog log = LogManager.GetLogger(typeof(ProjectTreePanelModel));
public ProjectTreePanelModel()
{
// 初始化命令
this.InitCommand();
}
/// <summary>
/// 初始化命令
/// </summary>
private void InitCommand()
{
this.LoadedCommand = new VCommand(this.Loaded);
this.FolderExpandCommand = new VCommand<DevExpress.Xpf.Grid.TreeList.NodeDoubleClickEventArgs>(this.FolderExpand);
this.FolderExpandingCommand = new VCommand<DevExpress.Xpf.Grid.TreeList.TreeViewNodeAllowEventArgs>(this.FolderExpanding);
this.FolderContentMenuOpendCommand = new VCommand(this.FolderContentMenuOpend);
this.CreateFolderCommand = new VCommand(this.CreateFolder, this.CanCreateFolder);
this.DeleteFolderCommand = new VCommand(this.DeleteFolder, this.CanDeleteFolder);
this.RefreshFolderCommand = new VCommand(this.RefreshFolder);
this.FileContentMenuOpendCommand = new VCommand(this.FileContentMenuOpend);
this.DeleteFileCommand = new VCommand(this.DeleteFile, this.CanDeleteFile);
this.RefreshFileCommand = new VCommand(this.RefreshFile, this.CanRefreshFile);
this.FileDoubleClickCommand = new VCommand(this.FileDoubleClick);
}
// ==========================================================================
// Config
// ==========================================================================
/// <summary>
/// 项目根路径
/// </summary>
private static readonly string PROJECT_ROOT_FOLDER = System.IO.Path.Combine(AppDomain.CurrentDomain.BaseDirectory, "Projects");
// ==========================================================================
// Controller & Service
// ==========================================================================
/// <summary>
/// 文件服务
/// </summary>
private FileService fileService = new FileService();
// ==========================================================================
// Property
// ==========================================================================
#region IsFolderLoading -- 文件夹是否处于加载中
private bool isFolderLoading;
/// <summary>
/// 文件夹是否处于加载中
/// </summary>
public bool IsFolderLoading
{
get { return isFolderLoading; }
set { isFolderLoading = value; this.RaisePropertyChanged(nameof(IsFolderLoading)); }
}
#endregion
#region IsFileLoading -- 文件是否处于加载中
private bool isFileLoading;
/// <summary>
/// 文件是否处于加载中
/// </summary>
public bool IsFileLoading
{
get { return isFileLoading; }
set { isFileLoading = value; this.RaisePropertyChanged(nameof(IsFileLoading)); }
}
#endregion
#region IsFilePanelEnabled -- 文件面板是否可用
private bool isFilePanelEnabled = true;
/// <summary>
/// 文件面板是否可用
/// </summary>
public bool IsFilePanelEnabled
{
get { return isFilePanelEnabled; }
set { isFilePanelEnabled = value; this.RaisePropertyChanged(nameof(IsFilePanelEnabled)); }
}
#endregion
#region RootFolder -- 根文件夹目录
private FolderModel rootFolder;
/// <summary>
/// 根文件夹目录
/// </summary>
public FolderModel RootFolder
{
get { return rootFolder; }
set { rootFolder = value; this.RaisePropertyChanged(nameof(RootFolder)); }
}
#endregion
#region FolderModels -- 文件夹列表
private ObservableCollection<FolderModel> folderModels;
/// <summary>
/// 文件夹列表
/// </summary>
public ObservableCollection<FolderModel> FolderModels
{
get { return folderModels; }
set { folderModels = value; this.RaisePropertyChanged(nameof(FolderModels)); }
}
#endregion
#region FileModels -- 文件列表
private ObservableCollection<FileModel> fileModels;
/// <summary>
/// 文件列表
/// </summary>
public ObservableCollection<FileModel> FileModels
{
get { return fileModels; }
set { fileModels = value; this.RaisePropertyChanged(nameof(FileModels)); }
}
#endregion
#region SelectedFolderModel -- 当前选中的文件夹
private FolderModel selectedFolderModel;
/// <summary>
/// 当前选中的文件夹
/// </summary>
public FolderModel SelectedFolderModel
{
get { return selectedFolderModel; }
set
{
selectedFolderModel = value;
this.RaisePropertyChanged(nameof(SelectedFolderModel));
this.FileModels = value?.Files;
this.SelectedFileModel = null;
this.TryLoadFolders(value, false);
this.TryLoadFiles(value, false);
}
}
#endregion
#region SelectedFileModel -- 当前选中的文件
private FileModel selectedFileModel;
/// <summary>
/// 当前选中的文件
/// </summary>
public FileModel SelectedFileModel
{
get { return selectedFileModel; }
set
{
FileModel oldValue = this.selectedFileModel;
FileModel newValue = value;
selectedFileModel = newValue;
this.RaisePropertyChanged(nameof(SelectedFileModel));
this.OnSelectedFileModelChanged(oldValue, newValue);
}
}
#endregion
#region SelectedFileModels -- 当前选中的文件列表
private IList selectedFileModels;
/// <summary>
/// 当前选中的文件列表
/// </summary>
public IList SelectedFileModels
{
get { return selectedFileModels; }
set { selectedFileModels = value; this.RaisePropertyChanged(nameof(SelectedFileModels)); }
}
#endregion
#region WaitCopyFileModels -- 待拷贝文件集合
private ObservableCollection<FileModel> waitCopyFileModels;
/// <summary>
/// 待拷贝文件集合
/// </summary>
public ObservableCollection<FileModel> WaitCopyFileModels
{
get { return waitCopyFileModels; }
set { waitCopyFileModels = value; this.RaisePropertyChanged(nameof(WaitCopyFileModels)); }
}
#endregion
// ==========================================================================
// Command
// ==========================================================================
#region LoadedCommand -- 加载命令
/// <summary>
/// 加载命令
/// </summary>
public VCommand LoadedCommand { get; set; }
/// <summary>
/// 加载
/// </summary>
private void Loaded()
{
this.RootFolder = new FolderModel(PROJECT_ROOT_FOLDER);
this.FolderModels = new ObservableCollection<FolderModel> { this.RootFolder };
this.TryLoadFolders(this.RootFolder, true);
}
#endregion
#region FolderExpandCommand -- 文件夹展开命令
/// <summary>
/// 文件夹展开命令
/// </summary>
public VCommand<DevExpress.Xpf.Grid.TreeList.NodeDoubleClickEventArgs> FolderExpandCommand { get; set; }
/// <summary>
/// 文件夹展开
/// </summary>
private void FolderExpand(DevExpress.Xpf.Grid.TreeList.NodeDoubleClickEventArgs e)
{
if (this.SelectedFolderModel == null || e.ChangedButton != System.Windows.Input.MouseButton.Left)
return;
this.SelectedFolderModel.IsExpand = !this.SelectedFolderModel.IsExpand;
}
#endregion
#region FolderExpandingCommand -- 文件夾打开前命令
/// <summary>
/// 文件夾打开前命令
/// </summary>
public VCommand<DevExpress.Xpf.Grid.TreeList.TreeViewNodeAllowEventArgs> FolderExpandingCommand { get; set; }
/// <summary>
/// 文件夾打开前
/// </summary>
/// <param name="e">事件参数</param>
private void FolderExpanding(DevExpress.Xpf.Grid.TreeList.TreeViewNodeAllowEventArgs e)
{
FolderModel folder = e.Node?.Content as FolderModel;
if (folder == null || folder.IsLoadedFolder)
return;
this.TryLoadFolders(folder, false);
}
#endregion
// -------------------------------------------------
// 文件夹
#region FolderContentMenuOpendCommand -- 文件夹右键菜单打开命令
/// <summary>
/// 文件夹右键菜单打开命令
/// </summary>
public VCommand FolderContentMenuOpendCommand { get; set; }
/// <summary>
/// 文件夹右键菜单打开
/// </summary>
private void FolderContentMenuOpend()
{
this.CreateFolderCommand?.RaiseCanExecute();
this.DeleteFolderCommand?.RaiseCanExecute();
}
#endregion
#region CreateFolderCommand -- 新建文件夹命令
/// <summary>
/// 新建文件夹命令
/// </summary>
public VCommand CreateFolderCommand { get; set; }
/// <summary>
/// 是否可以创建文件夹
/// </summary>
/// <returns>是否可以创建文件夹</returns>
private bool CanCreateFolder()
{
return this.SelectedFolderModel != null;
}
/// <summary>
/// 新建文件夹
/// </summary>
private void CreateFolder()
{
if (this.SelectedFolderModel == null)
return;
TextInputWindow window = new TextInputWindow();
window.Owner = this.GetWindow();
TextInputControlModel vm = window.DataContext as TextInputControlModel;
vm.Label = "文件夹名:";
window.ShowDialog();
if (window.DialogResult != true)
return;
try
{
FolderModel folder = this.fileService.CreateFolder(this.SelectedFolderModel, vm.Text);
this.SelectedFolderModel.Folders.Add(folder);
}
catch (Exception ex)
{
DXMessageBox.Show(ex.Message);
}
}
#endregion
#region DeleteFolderCommand -- 删除文件夹命令
/// <summary>
/// 删除文件夹命令
/// </summary>
public VCommand DeleteFolderCommand { get; set; }
/// <summary>
/// 是否可以删除文件夹
/// </summary>
/// <returns>是否可以删除文件夹</returns>
private bool CanDeleteFolder()
{
return this.SelectedFolderModel != null && this.SelectedFolderModel != this.RootFolder;
}
/// <summary>
/// 删除文件夹
/// </summary>
private void DeleteFolder()
{
if (this.SelectedFolderModel == null || this.SelectedFolderModel == this.RootFolder)
return;
var result = DXMessageBox.Show($"确定删除文件夹: \"{this.SelectedFolderModel.Path}\" ?", "提示", System.Windows.MessageBoxButton.YesNo);
if (result != System.Windows.MessageBoxResult.Yes)
return;
this.fileService.DeleteFolder(this.SelectedFolderModel);
this.SelectedFolderModel.Parent.Folders.Remove(this.SelectedFolderModel);
this.SelectedFolderModel = null;
}
#endregion
#region RefreshFolderCommand -- 刷新文件夹命令
/// <summary>
/// 刷新文件夹命令
/// </summary>
public VCommand RefreshFolderCommand { get; set; }
/// <summary>
/// 刷新文件夹
/// </summary>
private void RefreshFolder()
{
this.TryLoadFolders(this.RootFolder, true);
}
#endregion
// -------------------------------------------------
// 文件
#region FileContentMenuOpendCommand -- 文件右键菜单打开命令
/// <summary>
/// 文件右键菜单打开命令
/// </summary>
public VCommand FileContentMenuOpendCommand { get; set; }
/// <summary>
/// 文件右键菜单打开
/// </summary>
private void FileContentMenuOpend()
{
this.DeleteFileCommand.RaiseCanExecute();
}
#endregion
#region DeleteFileCommand -- 删除文件命令
/// <summary>
/// 删除文件命令
/// </summary>
public VCommand DeleteFileCommand { get; set; }
/// <summary>
/// 是否可以删除文件
/// </summary>
/// <returns>是否可以删除文件</returns>
private bool CanDeleteFile()
{
return this.SelectedFileModels != null && this.SelectedFileModels.Count > 0;
}
/// <summary>
/// 删除文件
/// </summary>
private void DeleteFile()
{
try
{
if (this.SelectedFileModels == null || this.SelectedFileModels.Count == 0)
return;
var result = DXMessageBox.Show($"确定删除项 ?", "提示", System.Windows.MessageBoxButton.YesNo);
if (result != System.Windows.MessageBoxResult.Yes)
return;
foreach (FileModel file in this.SelectedFileModels)
{
this.fileService.DeleteFile(file);
}
this.TryLoadFiles(this.SelectedFolderModel, true);
}
catch (Exception ex)
{
log.Error(ex);
}
}
#endregion
#region RefreshFileCommand -- 刷新文件命令
/// <summary>
/// 刷新文件命令
/// </summary>
public VCommand RefreshFileCommand { get; set; }
/// <summary>
/// 是否可以刷新文件
/// </summary>
/// <returns>是否可以刷新文件</returns>
private bool CanRefreshFile()
{
return this.SelectedFolderModel != null;
}
/// <summary>
/// 刷新文件
/// </summary>
private void RefreshFile()
{
if (this.SelectedFolderModel == null)
return;
this.TryLoadFiles(this.SelectedFolderModel, true);
}
#endregion
#region FileDoubleClickCommand -- 文件双击命令
/// <summary>
/// 文件双击命令
/// </summary>
public VCommand FileDoubleClickCommand { get; set; }
/// <summary>
/// 文件双击命令
/// </summary>
private void FileDoubleClick()
{
this.OnFileDoubleClick();
}
#endregion
// ==========================================================================
// Private Function
// ==========================================================================
/// <summary>
/// 选中的文件改变时触发
/// </summary>
/// <param name="oldValue">旧值</param>
/// <param name="newValue">新值</param>
protected virtual void OnSelectedFileModelChanged(FileModel oldValue, FileModel newValue)
{
}
/// <summary>
/// 文件双击时触发
/// </summary>
protected virtual void OnFileDoubleClick()
{
}
// ==========================================================================
// Private Function
// ==========================================================================
/// <summary>
/// 尝试加载文件夹
/// </summary>
/// <param name="folder">文件夹</param>
/// <param name="isForce">是否强制刷新</param>
private void TryLoadFolders(FolderModel folder, bool isForce)
{
if (folder == null)
return;
// 如果文件夹已经加载过文件 & 不需要强制刷新 那么不处理
if (folder.IsLoadedFolder && !isForce)
return;
this.IsFolderLoading = true;
ThreadHelper.SafeRun(() =>
{
var folders = this.fileService.GetFolders(folder.Path);
folders.ForEach(p =>
{
p.Parent = folder;
});
WPFHelper.BeginInvoke(() =>
{
folder.Folders.Clear();
folder.Folders.AddRange(folders);
folder.IsLoadedFolder = true;
this.IsFolderLoading = false;
});
});
}
/// <summary>
/// 尝试加载文件
/// </summary>
/// <param name="folder">文件夹</param>
/// <param name="isForce">是否强制刷新</param>
private void TryLoadFiles(FolderModel folder, bool isForce)
{
if (folder == null)
return;
// 如果文件夹已经加载过文件 & 不需要强制刷新 那么不处理
if (folder.IsLoadedFiles && !isForce)
return;
this.IsFileLoading = true;
ThreadHelper.SafeRun(() =>
{
var files = this.fileService.GetFiles(folder.Path, $"*{ApplicationConstants.PROJECT_FILE_EXTENSION}");
// 排除数据库日志文件
files = files.Where(p => !p.Name.ToLower().EndsWith(ApplicationConstants.PROJECT_FILE_LOG_NAME_SUFFIX)).ToList();
files.ForEach(p =>
{
p.Parent = folder;
});
WPFHelper.BeginInvoke(() =>
{
folder.Files.Clear();
folder.Files.AddRange(files);
folder.IsLoadedFiles = true;
this.IsFileLoading = false;
});
});
}
}
}
\ No newline at end of file
using DevExpress.Xpf.Core;
using log4net;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using VIZ.Framework.Core;
using VIZ.Package.Domain;
using VIZ.Package.Service;
namespace VIZ.Package.Module
{
/// <summary>
/// 保存项目窗口模型
/// </summary>
public class SaveProjectWindowModel : ProjectTreePanelModel
{
/// <summary>
/// 日志
/// </summary>
private readonly static ILog log = LogManager.GetLogger(typeof(SaveProjectWindowModel));
public SaveProjectWindowModel()
{
// 初始化命令
this.InitCommand();
}
/// <summary>
/// 初始化命令
/// </summary>
private void InitCommand()
{
this.SaveProjectCommand = new VCommand(this.SaveProject);
}
// ==========================================================================
// Config
// ==========================================================================
// ==========================================================================
// Controller & Service
// ==========================================================================
// ==========================================================================
// Property
// ==========================================================================
#region ProjectName -- 项目名
private string projectName;
/// <summary>
/// 项目名
/// </summary>
public string ProjectName
{
get { return projectName; }
set { projectName = value; this.RaisePropertyChanged(nameof(ProjectName)); }
}
#endregion
// ==========================================================================
// Command
// ==========================================================================
#region SaveProjectCommand -- 保存项目命令
/// <summary>
/// 打开项目命令
/// </summary>
public VCommand SaveProjectCommand { get; set; }
/// <summary>
/// 保存项目
/// </summary>
private void SaveProject()
{
if (this.SelectedFolderModel == null)
{
DXMessageBox.Show("请选择要保存项目的目录");
return;
}
if (string.IsNullOrWhiteSpace(this.ProjectName))
{
DXMessageBox.Show("请输入项目名");
}
string file = this.ProjectName;
if (!this.ProjectName.ToLower().EndsWith(ApplicationConstants.PROJECT_FILE_EXTENSION))
{
file = $"{file}{ApplicationConstants.PROJECT_FILE_EXTENSION}";
this.ProjectName = file;
}
string path = System.IO.Path.Combine(this.SelectedFolderModel.Path, file);
if (System.IO.File.Exists(path))
{
var result = DXMessageBox.Show($"项目:\"{file}\" 已经存在,是否覆盖", "提示", MessageBoxButton.YesNo);
if (result != MessageBoxResult.Yes)
return;
}
Window window = this.GetWindow();
window.DialogResult = true;
window.Close();
}
#endregion
// ==========================================================================
// protected Function
// ==========================================================================
/// <summary>
/// 选中的文件改变时触发
/// </summary>
/// <param name="oldValue">旧值</param>
/// <param name="newValue">新值</param>
protected override void OnSelectedFileModelChanged(FileModel oldValue, FileModel newValue)
{
this.ProjectName = newValue?.Name;
}
}
}
\ No newline at end of file
......@@ -131,10 +131,18 @@
</Compile>
<Compile Include="Plugin\Model\PluginNavigationConfig.cs" />
<Compile Include="Plugin\Service\IPluginService.cs" />
<Compile Include="ProjectManager\View\ProjectManagerWindow.xaml.cs">
<DependentUpon>ProjectManagerWindow.xaml</DependentUpon>
<Compile Include="ProjectManager\ViewModel\SaveProjectWindowModel.cs" />
<Compile Include="ProjectManager\ViewModel\ProjectTreePanelModel.cs" />
<Compile Include="ProjectManager\View\SaveProjectWindow.xaml.cs">
<DependentUpon>SaveProjectWindow.xaml</DependentUpon>
</Compile>
<Compile Include="ProjectManager\View\OpenProjectWindow.xaml.cs">
<DependentUpon>OpenProjectWindow.xaml</DependentUpon>
</Compile>
<Compile Include="ProjectManager\ViewModel\OpenProjectWindowModel.cs" />
<Compile Include="ProjectManager\View\ProjectTreePanel.xaml.cs">
<DependentUpon>ProjectTreePanel.xaml</DependentUpon>
</Compile>
<Compile Include="ProjectManager\ViewModel\ProjectManagerWindowModel.cs" />
<Compile Include="Resource\MediaResource\Controller\Model\ms.cs" />
<Compile Include="Resource\MediaResource\Core\MHResourceFileDoubleClickEventArgs.cs" />
<Compile Include="Resource\MediaResource\Core\MHResourceSelectedFileChangedEventArgs.cs" />
......@@ -369,6 +377,7 @@
</ItemGroup>
<ItemGroup>
<Folder Include="Main\Controller\" />
<Folder Include="ProjectManager\Model\" />
</ItemGroup>
<ItemGroup>
<Page Include="ControlObject\FieldEdit\Edit\FloatEdit\FloatEditPanel.xaml">
......@@ -407,7 +416,15 @@
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ProjectManager\View\ProjectManagerWindow.xaml">
<Page Include="ProjectManager\View\SaveProjectWindow.xaml">
<Generator>MSBuild:Compile</Generator>
<SubType>Designer</SubType>
</Page>
<Page Include="ProjectManager\View\OpenProjectWindow.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
<Page Include="ProjectManager\View\ProjectTreePanel.xaml">
<SubType>Designer</SubType>
<Generator>MSBuild:Compile</Generator>
</Page>
......
using log4net;
using System;
using System.Collections.Generic;
using System.IO;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using VIZ.Package.Domain;
namespace VIZ.Package.Service
{
/// <summary>
/// 文件服务
/// </summary>
public class FileService
{
/// <summary>
/// 日志
/// </summary>
private readonly static ILog log = LogManager.GetLogger(typeof(FileService));
/// <summary>
/// 获取指定路径下的所有文件夹
/// </summary>
/// <param name="path">指定路径</param>
/// <returns>文件夹</returns>
public List<FolderModel> GetFolders(string path)
{
List<FolderModel> folders = new List<FolderModel>();
if (string.IsNullOrWhiteSpace(path) || !System.IO.Directory.Exists(path))
return folders;
foreach (string folder in System.IO.Directory.GetDirectories(path))
{
FolderModel model = new FolderModel(folder);
folders.Add(model);
}
return folders;
}
/// <summary>
/// 获取指定路径下的文件
/// </summary>
/// <param name="path">指定路径</param>
/// <returns>文件</returns>
public List<FileModel> GetFiles(string path)
{
return this.GetFiles(path, null);
}
/// <summary>
/// 获取指定路径下的文件
/// </summary>
/// <param name="path">指定路径</param>
/// <param name="searchPattern">匹配模式</param>
/// <returns>文件</returns>
public List<FileModel> GetFiles(string path, string searchPattern)
{
List<FileModel> files = new List<FileModel>();
if (string.IsNullOrWhiteSpace(path) || !System.IO.Directory.Exists(path))
return files;
string[] fileArray = string.IsNullOrWhiteSpace(searchPattern) ?
System.IO.Directory.GetFiles(path) :
System.IO.Directory.GetFiles(path, searchPattern);
foreach (string file in fileArray)
{
FileModel model = new FileModel(file);
files.Add(model);
}
return files;
}
/// <summary>
/// 创建文件夹
/// </summary>
/// <param name="parent">父级别文件夹</param>
/// <param name="name">文件夹名称</param>
/// <returns>文件夹模型</returns>
public FolderModel CreateFolder(FolderModel parent, string name)
{
if (parent == null)
throw new ArgumentNullException(nameof(parent));
if (string.IsNullOrWhiteSpace(name))
throw new ArgumentNullException(nameof(name));
string path = System.IO.Path.Combine(parent.Path, name);
if (System.IO.Directory.Exists(path))
throw new Exception($"文件夾: {path} 已经存在.");
Directory.CreateDirectory(path);
FolderModel folder = new FolderModel(path);
folder.Parent = parent;
return folder;
}
/// <summary>
/// 删除文件夹
/// </summary>
/// <param name="folder">文件夹</param>
public void DeleteFolder(FolderModel folder)
{
if (folder == null)
throw new ArgumentNullException(nameof(folder));
if (!System.IO.Directory.Exists(folder.Path))
throw new Exception($"文件夹: {folder.Path} 不存在");
System.IO.Directory.Delete(folder.Path, true);
}
/// <summary>
/// 删除文件
/// </summary>
/// <param name="file">文件</param>
public void DeleteFile(FileModel file)
{
if (file == null)
throw new ArgumentNullException(nameof(file));
System.IO.File.Delete(file.Path);
}
/// <summary>
/// 拷贝文件
/// </summary>
/// <param name="files">文件集合</param>
/// <param name="dstFolderParent">目标文件夹集合</param>
/// <returns>拷贝文件</returns>
public List<FileModel> CopyFile(List<FileModel> files, FolderModel dstFolderParent)
{
if (files == null)
throw new ArgumentNullException(nameof(files));
if (dstFolderParent == null)
throw new ArgumentNullException(nameof(dstFolderParent));
List<FileModel> list = new List<FileModel>();
if (files.Count == 0)
return list;
foreach (FileModel file in files)
{
string dstPath = System.IO.Path.Combine(dstFolderParent.Path, file.Name);
System.IO.File.Copy(file.Path, dstPath);
FileModel model = new FileModel(dstPath);
list.Add(model);
}
return list;
}
}
}
......@@ -70,6 +70,7 @@
<ItemGroup>
<Compile Include="DB\Conn\ConnService.cs" />
<Compile Include="DB\ControlObject\ControlObjectService.cs" />
<Compile Include="DB\File\FileService.cs" />
<Compile Include="DB\Page\PageService.cs" />
<Compile Include="DB\Registry\RegistryService.cs" />
<Compile Include="Logic\Plugin\PluginService.cs" />
......
......@@ -62,6 +62,7 @@
<Reference Include="DevExpress.Data.v22.1, Version=22.1.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.Printing.v22.1.Core, Version=22.1.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.Xpf.Core.v22.1, Version=22.1.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="DevExpress.Xpf.Themes.VS2019Dark.v22.1, Version=22.1.6.0, Culture=neutral, PublicKeyToken=b88d1754d700e49a, processorArchitecture=MSIL" />
<Reference Include="LiteDB, Version=5.0.15.0, Culture=neutral, PublicKeyToken=4ee40123013c9f27, processorArchitecture=MSIL">
<HintPath>..\packages\LiteDB.5.0.15\lib\net45\LiteDB.dll</HintPath>
</Reference>
......
Markdown is supported
0% or
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment