欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

桌面应用开发的日子(二):实现文件资源管理列表树加载

程序员文章站 2022-06-18 14:14:35
已矣乎!寓形宇内复几时?曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑!————《归去来兮辞并序》·陶渊明 实现效果 获取本地逻辑驱动器、文件夹、文件 Directory.GetLogicalDrives ......

已矣乎!寓形宇内复几时?曷不委心任去留?胡为乎遑遑欲何之?富贵非吾愿,帝乡不可期。怀良辰以孤往,或植杖而耘耔。登东皋以舒啸,临清流而赋诗。聊乘化以归尽,乐夫天命复奚疑!————《归去来兮辞并序》·陶渊明

实现效果
桌面应用开发的日子(二):实现文件资源管理列表树加载

获取本地逻辑驱动器、文件夹、文件

directory.getlogicaldrives();
directory.getdirectories(fullpath); // 返回指定目录中的子目录
directory.getfiles(fullpath); // 返回指定目录中的文件

// 截取文件或文件夹名称
public static string getfilefoldername(string path)
{
    if (string.isnullorempty(path))
        return string.empty;
    path = path.replace("/", "\\");

    var lastindex = path.lastindexof("\\");
    if (lastindex <= 0)
        return path;

    return path.substring(lastindex + 1);
}

通过mvvm模式,实现后台数据与ui进行绑定,下面是树ui结构定义和实体,视图模型的定义

<treeview x:name="foldertreeview" grid.row="1" itemssource="{binding items}">
    <treeview.itemcontainerstyle>
        <style targettype="{x:type treeviewitem}">
            <setter property="isexpanded" value="{binding isexpanded,mode=twoway}"/>
        </style>
    </treeview.itemcontainerstyle>
    <treeview.itemtemplate>
        <hierarchicaldatatemplate itemssource="{binding children}">
            <stackpanel orientation="horizontal">
                <textblock margin="3" fontfamily="{staticresource iconfont}" fontsize="26" foreground="{binding iconcolor}" text="{binding icon}" />
                <textblock  verticalalignment="center" fontsize="18" text="{binding name}"/>
            </stackpanel>
        </hierarchicaldatatemplate>
    </treeview.itemtemplate>
</treeview>
public class directoryitem
{
    public string fullpath { get; set; }
    public directoryitemtype type { get; set; }
    public string name
    {
        get
        {
            return this.type == directoryitemtype.drive ?
              this.fullpath :
              directorystructure.getfilefoldername(this.fullpath);
        }
    }
    public string icon { get; set; }
    public brush iconcolor { get; set; }
}
public class directoryitemviewmodel : baseviewmodel
{
    /// <summary>
    /// 全路径
    /// </summary>
    public string fullpath { get; set; }

    /// <summary>
    /// 成员类型
    /// </summary>
    public directoryitemtype type { get; set; }

    /// <summary>
    /// 成员名称
    /// </summary>
    public string name
    {
        get
        {
            return this.type == directoryitemtype.drive ?
              this.fullpath :
              directorystructure.getfilefoldername(this.fullpath);
        }
    }

    /// <summary>
    /// 成员图标
    /// </summary>
    public string icon { get; set; }

    /// <summary>
    /// 图标颜色
    /// </summary>
    public brush iconcolor { get; set; }

    /// <summary>
    /// 子成员
    /// </summary>
    public observablecollection<directoryitemviewmodel> children { get; set; }

    /// <summary>
    /// 表示成员是否可以展开
    /// </summary>
    public bool canexpend { get { return this.type != directoryitemtype.file; } }

    /// <summary>
    /// 展开/收缩的处理
    /// </summary>
    public bool isexpanded
    {
        get
        {
            return this.children?.count(x => x != null) > 0;
        }
        set
        {
            if (value)
                expand();
            else
                clearchildren();
        }
    }


    public icommand expandcommand { get; set; }

    public directoryitemviewmodel()
    {
        this.expandcommand = new relaycommand(expand);
        this.clearchildren();
    }

    private void clearchildren()
    {
        this.children = new observablecollection<directoryitemviewmodel>();
        if (this.type != directoryitemtype.file)
            this.children.add(null);
    }

    /// <summary>
    /// 展开目录并找到所有子成员
    /// </summary>
    private void expand()
    {
        if (this.type == directoryitemtype.file)
            return;
        var children = directorystructure.getdirectcontents(this.fullpath);
        var selector = children.select(x => new directoryitemviewmodel()
        {
            fullpath = x.fullpath,
            type = x.type,
            icon = x.icon,
            iconcolor = x.iconcolor
        });
        this.children = new observablecollection<directoryitemviewmodel>(selector);
    }
}
public class directorystructureviewmodel : baseviewmodel
{
    public observablecollection<directoryitemviewmodel> items { get; set; }

    public directorystructureviewmodel()
    {
        var children = directorystructure.getlogicaldrives();
        var selector = children.select(x =>
        new directoryitemviewmodel()
        {
            fullpath = x.fullpath,
            type = x.type,
            icon = x.icon,
            iconcolor = x.iconcolor
        });
        this.items = new observablecollection<directoryitemviewmodel>(selector);
    }
}

构建基类视图模型

[addinotifypropertychangedinterface]
public class baseviewmodel : inotifypropertychanged
{
    public event propertychangedeventhandler propertychanged=(sender, e)=>{}; //数据变化时通知前端
}

通过命令,点击逻辑器或文件夹时,加载子元素

    public class relaycommand : icommand
    {
        private action action;

        public event eventhandler canexecutechanged = (sender, e) => { };

        public relaycommand(action action)
        {
            this.action = action;
        }

        public bool canexecute(object parameter)
        {
            return true;
        }

        public void execute(object parameter)
        {
            action();
        }
    }

相关参考:
https://github.com/fody/propertychanged