By nttcOnline Payday Loans

FileExplorer3

FileExplorer3

ToolWindow and TabControl

FileExplorer3 is an WPF based control that emulate most aspect of Shell Explorer, you can use it to display shell objects or any hierarchical data.

You can use it as a standalone window, as a FilePicker (Open or Save), FolderPicker, or embed it as a part of your UI.

You can find the documentation on CodeProject, and the project source code on CodePlex.

WPF UIEventHub – MultiSelect and DragnDrop

FileExplorer3.DropnDrop

WPF UIEventHub register a number of events and distributed to registered UIEventProcessor, available UIEventProcessor included MultiSelectEventProcessor and DragDropEventProcessor, which is an update for SelectionHelper and FileDragDropHelper static class.

How to use?

UIEventHub is created to support ListBox/View and TreeView, you can use xaml syntax or cs code to register the UIProcessors.

Xaml:

<ListView Grid.Column="1" Grid.Row="2" >
<bc:UIEventAdapter.Processors>
<bc:DragDropEventProcessor EnableDrag="True" EnableDrop="True" />
<bc:MultiSelectEventProcessor UnselectAllCommand="{Binding UnselectAllCommand}" />
</bc:UIEventAdapter.Processors>
</ListView>

Cs:

treeView.RegisterEventProcessors(new DragDropEventProcessor());
listView.RegisterEventProcessors(new DragDropEventProcessor(), new MultiSelectEventProcessor(vm1.UnselectAllCommand));

Please noted that TreeView does not support Multi-Select.

For Drag and Drop, in addition to register the UIProcessor, you also need to implement ISupportDrag/Drop/DragHelper/DropHelper for the system to work, it will be described below.

UIEventProcessor

///
/// Allow one application (e.g. dragging) to handle events from an control.
/// 

public interface IUIEventProcessor
{
   IScriptCommand OnMouseDrag { get; }
   IScriptCommand OnMouseDragOver { get; }
   ....
}

public interface IScriptCommand
{
    string CommandKey { get; }

    IScriptCommand Execute(ParameterDic pm);
    bool CanExecute(ParameterDic pm);
}

UIEventProcessor included a number of IScriptCommand.  When certain event is triggered, a ScriptRunner is created and run the appropriate IScriptCommand (e.g. Control.MouseMove -> OnMouseMove).  Because IScriptCommand.Execute() can return another IScriptCommand, complex operations are broken up into multiple IScriptCommands.

public class ScriptRunner : IScriptRunner
{
   public void Run(Queue<IScriptCommand> cmds, ParameterDic initialParameters)
   {
      ParameterDic pd = initialParameters;

      while (cmds.Any())
      {
         var current = cmds.Dequeue();
         if (current.CanExecute(pd))
         {
             var retCmd = current.Execute(pd);
             if (retCmd != null)
                cmds.Enqueue(retCmd);
         }
         else throw new Exception(String.Format("Cannot execute {0}", current));
      }
   }
}

 

Using UIEventHub, Drag and Drop Helper and MultiSelect Helper (static classes) in FileExplorer is converted to DragDropEventProcessor and MultiSelectEventProcessor.

DragDropEventProcessor

DragDropUIEventProcessor

DragDropEventProcessor enable dragging one or multi object from one DataContext (which implements ISupportDrag) to another DataContext (which implements ISupportDrop).

Control does not have Drag event, it’s trigger when MouseMove (while a mouse button is pressed) more than SystemParameters.MinimumHorizontalDragDistance  or MinimumVerticalDragDistance.

public interface ISupportDragHelper
{
    ISupportDrag DragHelper { get; }
}

public interface ISupportDrag
{        
    bool HasDraggables { get; }
    IEnumerable<IDraggable> GetDraggables();
    DragDropEffects QueryDrag(IEnumerable<IDraggable> draggables);
    IDataObject GetDataObject(IEnumerable<IDraggable> draggables);        
    void OnDragCompleted(IEnumerable<IDraggable> draggables, IDataObject da, DragDropEffects effect);
}

So whenever user trying to drag, this processor will check if DataContext supports ISupportDrag or ISupportDragHelper, and if HasDraggables equals true, it then calls GetDraggables() and GetDataObject() to get an dataobject, and initialize the drag  (using System.Windows.DragDrop.DoDragDrop).

Because it uses DoDragDrop, you can create a DataObject for shell file drop (to Windows Explorer, VS, but doesn’t work on notepad).  For files thats not exists in the file system, you can use the included VirtualDataObject to delay creation of the files as well.

That’s the drag operation, then we have drop operation.

Whenever items (DataObject) is dragged over or dropped on a registered control, the processor looks up the LogicalTree for a DataContext that implements ISupportDrop and it’s IDroppable equals true, so If DataContext of the current item, for examples, ListViewItem, does not support ISupportDrop, it will lookup the ListView.

public interface ISupportDropHelper
{
    ISupportDrop DropHelper { get; }
}

public interface ISupportDrop
{
    bool IsDraggingOver { set; }
    bool IsDroppable { get; }
    string DropTargetLabel { get; }
    QueryDropResult QueryDrop(IDataObject da, DragDropEffects allowedEffects);
    IEnumerable<IDraggable> QueryDropDraggables(IDataObject da);
    DragDropEffects Drop(IEnumerable<IDraggable> draggables, IDataObject da, DragDropEffects allowedEffects);
}

DragDropEventProcessor show an adorner (DragAdorner) under your mouse cursor, it has an ItemsControl which loaded from ISupportDrop.QueryDropDraggables().  You have to specify a ItemTemplate for it, without template it shows the items in text.

<DataTemplate x:Key="dragnDropHintTemplate">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Value}" />
        <TextBlock Text="[drag]" Foreground="Gray" />
    </StackPanel>
</DataTemplate>
<Style TargetType="{x:Type ListView}" BasedOn="{StaticResource {x:Type ListBox}}" >
    <Setter Property="ItemTemplate" Value="{StaticResource dragnDropItemTemplate}" />
    <Setter Property="ItemsSource" Value="{Binding Items}" />
    <Setter Property="AllowDrop" Value="True" />
    <Setter Property="bc:AttachedProperties.DragItemTemplate" 
            Value="{StaticResource dragnDropHintTemplate}" />
</Style>

The drag adorner also contains a textblock that shown “Copy n items to {target}”, the target text is loaded from ISupportDrop.DropTargetLabel.

This drag adorner is reside in an adorner layer named PART_DragDropAdorner, this adorner can be shared, so it’s ideal to put it under root control like Windows or Page.

<AdornerDecorator x:Name="PART_DragDropAdorner" />

QueryDrop allow you to return multiple supported DragDropEffects and one preferred DragDropEffect.  If user initiate the drag and drop in the same application using right mouse, a context menu is shown (ShowAdornerContextMenu) for choosing the desired DragDropEffect.  In this case, ISupportDrag.OnDragCompleted() is called after user select a DragDropEffect, instead of immediately after Drop.

MultiSelectEventProcessor

MultiSelectUIEventProcessor

MultiSelectEventProcessor allow you to choose multiple items by dragging with mouse on ListView, this is very basic functionality and it’s wired that the framework still doesn’t provide it.

When dragging, an adorner (SelectionAdorner) is shown, it has 0.5 opacity so the items below are visible.  The adorner is reside in adorner layer inside the control.  The items under the SelectionAdorner have it’s AttachedProperties.IsSelecting set to true, you can highlight your items when selecting.

<DataTemplate x:Key="dragnDropItemTemplate">
    <StackPanel Orientation="Horizontal">
        <TextBlock Text="{Binding Value}" />
        <TextBlock Text="[ing]" Foreground="Blue"
                Visibility="{Binding (bc:AttachedProperties.IsSelecting),
                    RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}},
                    Converter={StaticResource btvc}}" />
        <TextBlock Text="[ed]" Foreground="Green"
                Visibility="{Binding IsSelected, Converter={StaticResource btvc}}" />
    </StackPanel>
</DataTemplate>

The selection lookup routines (FindSelectedItems) is a combination of the first and second articles, it uses first/last selected item for GridView, IChildInfo for panels that support IChildInfo, otherwise HitTest.

public interface IChildInfo
{
    Rect GetChildRect(int itemIndex);
}

If HitTest, MultiSelectEventProcessor cannot correctly return all selected items (they cannot be hit test if destroyed or not shown), so Highlight/SelectItemsByUpdate are used, which add or remove items from the selection list.  For the another two methods, HighlightItems/SelectItems are used, which replace the selection list.

 

Conclusion

The reason for rewriting this two static class is to simplify it so I can implement touch related code.  I cannot implement them yet because I don’t have a machine that support touch right now, but I found implement the code in a scriptable way (learned from REST in Pratice) can make the code reusable and easy to read.

I hope this rewrite can reduce the effort needed to implement other touch based code and other gesture.

This article have been posted on .  You can find a list of my articles here.

WPF BreadcrumbTree

WPF BreadcrumbTree is a Breadcrumb that inherited from TreeView.

Most breadcrumb are from ItemsControl, although easier to develop, it usually parse the hierarchy using non-standard way (e.g. Reflection or Binding from UI), or let you assign the Hierarchical items yourself.  These method are not very MVVM friendly.

BreadcrumbTree uses your HierarchicalDataTemplate instead, it’s a treeview except it collapse the unrelated items (which are not loaded), and the node is binded to your ViewModel (which implements IEntriesHelper, ITreeSelector and ITreeNodeSelector).

Full article can be found on CodeProejct

Cofe3 Initial Release

Cofe3 is a set of libraries that enables developers to build their home cloud services for their specific kind of entries, which enables the user to host them on their own computer, and using it to serve their own thin client computer like smart phone and tablet via the web browser or apps. This library is released under the LGPL license.

I have tried hard to code the project, the performance and feature set are still unsatisfactory, I think there are some flaws in my design, and the scope have grown too large over time.  It took too long and the development has to be stopped at this moment, until I can figure out how to improve the product.

Still, time spent and the project is working.  I have released the source and two part articles (part1/part2)  document my project.

From the Author (2012)

What is COFE2

Sorry for lack of update for near a year.

Although based on previous history lack of update usually means the I am working on a new product, together with the Windows 8 will be released soon. But no, I haven’t touched the UI part for many months, although once I got my Windows 8 tablet I will likely be tempted to port my FileExplorer to the metro interface, but nothing has been coded now, I haven’t read any new WPF/W8 books for months.

Several things noticed last year, which somehow shifted my direction of development:

Firstly, free online storage services become more and more common, services like DropBox exists well before, but it’s main use was to transport document. The new services last year including iCloud, Google Drive, SkyDrive etc are aim at storing your files online, provide some kind of cloud online file manager.

Secondly, because they are now file manager, they have to use your data, for examples, create index for text document, thumbnail for images, convert video to appropriate formats, user gave them the right to use their data, by accepting the license, but the terms favored the company and the user cannot oversee if the license is followed fairly.

Thirdly, most user, spent most of their time on their mobile computer running Apps, including native and HTML applications, which consume internet resources directly, including the user contents provided by those free online storage provider, DropBox, GoogleDrive and other all provides a set of API to access the user contents, user have to give permission to their Apps provider in order to access their files, over the time, user are giving more and more companies for permission to access all their files.  If document that’s intended to be private, is leaked, there’s no way to trace who to blame.

Lastly, Zipware was useful because people can zip a set of files and transfer to another computer (e.g. share with friends), but because of the above reasons, these zip achieves are considered as an obstacle for mobile access, and because bandwidth is not a factor nowadays, people tend to avoid compressing their files, or do it less frequently, and as the result is that most people would be satisfied with the unzip shell extension provided by windows.

I thought, although sooner or later most users will run thin client, and store their files on somewhere on the WWW, but beside relying online free or paid cloud storage services, people should have choice and have their own private cloud storage solution. To my surprise, there was no choice for that (was, I know there’s a few now).

These are the reasons makes me want to develop COFE2 as my next project, before continue, let me briefly explain what COFE is:

COFE1, or originally CAKE Operated File Explorer, is written as a component used by QuickZip 5.x to access the file system, it enable the program to treat archive as directory. Because COFE1 is a product written after my DirectoryInfoEx, so in addition to shell directory (e.g. Desktop), COFE1 can access user defined directory (e.g. Bookmarks and Archive), using a interface similar to the System.IO.FileSystemInfo class provided by the .Net library.

COFE2, or Cloud Over IFileSystemInfo Extension, is a rewrite of COFE1. COFE2 has a similar interface as FileSystemInfo, called IFileSystemInfo, in addition to that, a RESTful web interface to provide API for online access of shared directories (volumes).  Currently, a volume can either be a directory, or an Isolated Storage (.Net class).

All properties of a IFileSystemInfo, including file name and checksum are considered as metadata, this allows extensibility; developer can define and implement their own properties, and store them in database for search purpose, the syntax of search is similar to search engine.

My idea of COFE2 is simple, a private cloud storage running on your working computer, you can access your files via a mobile HTML5 web page, expose a RESTful API so other Apps can access the storage with some coding, while the back end is still IFileSystemInfo, something that’s familiar to most developers.

Some may argue that a personal FTP server, or some home network attached storage can enable file sharing among family members or friends with ease, and they exists since a long time ago. The major problem of these implementations is that their protocol disallow access of mobile devices efficiently. The another problem is that they serve as file sharing only, cannot perform other actions like search, their protocol simply don’t have that defined.

COFE2 involved many new technologies to me, including Entity framework, RESTful web services, HTML5, JQuery and CoffeeScript, together with the extremely large scope, COFE2 was a big challenge for me. On the another side, the experience learned from COFE1, and several extremely well written books, including REST in pratices for how to expose features to web services, it also have full examples for .NET although it was a little bit outdated, Brownfield Application Development in .NET for how to automate tests and build files, thus I don’t have to do it myself. This makes the development possible, enabling me to build the backend (IFileSystemInfo) and frontend (http://localhost/entry) from void.

COFE2 is uncompleted at this moment, that’s still a lot of work before the component can be fully functioning, but some basic functionality is written, for examples, browsing a specific folder, or search using parameters via a mobile web page.  On the another side, it doesn’t have everything required to run on production environment, specifically, it lacks of security protection, a desktop UI like Quick Zip 5, and the ability to change the filesystem via the web page (like upload or move).

New ideas do come in as I developing the product, for examples, can I log the Filesystem change events in database, and make it consumable via rss feeds?  This makes the scope growing over time.

Although not completed, I have released COFE2 under GPL open source license, so component and software user can know what is running on their system.  The development of COFE2 will continue, and I hope when COFE2 is becoming more and more functional, it can give user another choice of how to manage their personal files and use them online.