Click here to Skip to main content
15,867,568 members
Articles / Desktop Programming / WPF

A Drag and Drop ListLauncher with fold-able Groups

Rate me:
Please Sign up or sign in to vote.
5.00/5 (4 votes)
3 Mar 2017CPOL7 min read 8.9K   357   11  
Launch additionally a limited number of hand picked Programs, Documents or Folders from the taskbar

Image 1

Drag and drop Listlauncher to visually launch hand picked items

Introduction

The major purpose of this article is to make the download of the ListLauncher available, a little utility to launch some hand picked programs, documents or folders.

In 2011, I wrote my first WPF hobby program, the ListLauncher as a little UI experiment. This utility could be downloaded from my hobby website, but since that website has gone, I decided to make this small utility available in this CodeProject article.

In the third paragraph of this article, I give a program description of the ListLauncher. The description is from some copy and paste from my old website page. Despite the somewhat promotional description, the utility is rather simple and has its limitations (no URLs, known folders, program command line options, etc.).

The choice to use utilities to organize and launch your most frequent used programs is quite personal. I missed this functionality to manually organize programs in the LIST of the Windows 10 Start Menu so nowadays, I use the Classic Shell start menu. In the W10 File Explorer, we have the quick access with similar capabilities.

In the last paragraph, I will discuss shortly the code. The code is just an additional download, be warned that the code is not an example of good (MVVM) programming. It was my first WPF program and originally, I used XAML but no MVVM.

Background

The program originated for my interest in presenting items by variations in sizes and grouping, in combination with (hierarchical) search paths that can be discovered and remembered by the user.

This interest, combined with hand picked items (for the collector effect or the Ikea "I made it myself" effect) resulted in some programs like this "1D" ListLauncher, the "2D" desktop circles launcher with tabbed planes and icons freely placed on a circle to organize a larger number of items and PlayMyMusicFolders a former W8 app where hand picked Music Folders were presented and organized in a similar way as the "Immersive" Modern Windows 8.0 Start Menu (nowadays Groove is OK to play local music folders).

Using the ListLauncher

There are many ways to organize and quickly access your daily favourite programs, folders and documents in Windows (Short-cut keys, Desktop Icons, TaskBar Icons, Menu Start, etc.).

The List Launcher is a basic program and explores longer lists for people who like additional hand picked lists to organize and visually launch their favourite programs, documents or folders.

In the figure below, left part, we see The List Launcher attached on the taskbar (White Rectangular Icon). One single left click and The List window appears, and 1 extra single mouse left click on an item launches the selected application, opens the document or folder and minimizes the List. Pressing the "Ctrl" key and an item launches the item without minimizing the list, for opening multiple folders in the file explorer.

Image 2

"The List Launcher"attached to taskbar and its main window. Launching secondary items in 2 mouse clicks.

The list consists of launch-able short cuts of applications, documents or folders, combined with optional separators/group headers. A separator is shown as a blue line with a text to visually organize the list. It is possible to fold/unfold the groups by clicking its separator. A folded group is presented by a separator with dots. In this way, the information presented can be limited, but some extra information is available at the cost of an extra mouse click.

To organize the list:

  • You always begin with an empty list in item-launching mode.
  • By clicking on the "+" button, you get a window to add separators, files and folders. See figure below. If you like, you can enter first all separators/group headers without closing the add separators window.

Image 3

  • If the list is not empty, you can drag files, folders and drives into the list.
  • To organize the order of the list, you can also use drag and drop. The dragged item will appear below the selected drop item.
  • The two buttons with the 2 dots will Fold and Unfold all separators.
  • When all separators are Folded, you can drag drop folded groups as a whole, non folded items are moved as individual items.
  • Pressing the "Delete" key and clicking on an item will remove the short cut. If a folded separator is clicked, only the separator is deleted.
  • Note that the intention is that the list of favourites is rather stable, hand picking the items is done once. It will take some time to get acquainted and finding items in the list automatically.

The ListLauncher is written in C# (WPF) for Windows 7 to attach it to the taskbar. Jump lists are limited in length. Longer lists require adaptations of the register and affect the Menu Start. The ListLauncher does not have that limitation because it constructs the list itself. The standard chrome (close button, etc.) is moved to the bottom of the window to look extra cool and to limit the mouse travel distance from taskbar to close or minimize the window. Although the main part of the list items are handpicked once, the drag and drop gives the utility an extra for small adaptations. The program saves XML files ListLaucher.ini and .old in its folder.

A Small Note on the Additional Code

As mentioned in the introduction, the code is just an additional download, be warned that the code is not an example of good programming. It was my first WPF program and originally, I used XAML but no MVVM.

To make the code a little bit more presentable for this article, I did an extra iteration and added a ViewModel for the List data, but I did not remove any code behind (modal dialogues, drag and drop), so it is not such a good MVVM sample.

The code can be used if you are not quite happy with the program and want to do some minor UI changes like make the items presented in the list larger. For major changes (like a harmonica list with Mouse Scroll or make a more general User Control for a List with fold-able groups), start from scratch.

Image 4

See the figure above for the project solution and see the code below for the interface IMyListElement:

C#
 public interface IMyListElement
 {
    BitmapSource Icon { get; set; }

    string FriendlyName { get; set; }

    string FullName { get; set; }


    // We could also make different classes for ExtraHeader and regular short-cuts:

    bool IsExtraGroupHeader { get; set; }
    bool IsFolded { get; set; }

    // Computed from IsFolded and IsExtraGroupHeader
    bool IsHidden { get; set; }
}

The concrete class MyListElement is focused on the ListLauncher. The FullName depicts the launch path for launch-able items, the FriendlyName is shown in the list. If the backing field of the Icon is null, the Icon is retrieved in the getter from the FullName.

I did choose to make special items for the extra group headers/separators. I did also choose to use a bool IsExtraGroupHeader instead of using special child classes. The property IsHidden is computed in the getter from IsExtraGroupHeader and IsFolded.

Main functions in MylistHelper.cs are Load, Save and MoveWithExtraHeaderOptions( list1, indexFrom, indexTo). The latter function handles the drag and drop logic for items in the list with groups. In this helper, I use using MyListType = System....ObservableCollection<MyList.MyListElement>. Using the interface <IMyListElement> is more general but it seems we have then to do some extra work for XML serialization.

See below for the interface of the main view model below:

C#
  public interface IMainVm
  {
    // Save in setter:
    ObservableCollection<mylistelement> MyList { get; set; }

    ICommand FoldAll { get; }
    ICommand UnFoldAll { get; }

    void OnfoldAll(object p);
    void OnUnfoldAll(object p);

    // directly called in code behind:
    void InsertToMyList(int droppedOnIndex, string fullName, string friendlyName = "");
    void OnDragDrop(int indexTo, int indexFrom);

    void OnDelete(int deleteIndex);

    // OnSetSave();
    void OnToggleIsFoldedOfHeader(int HeaderIndex);
  } 
</mylistelement>

Note that there is a lot of code behind in the view/ XAML files so we find in the code behind for example calls to ((vm.MainVm)DataContext).InsertToMyList(0, fullName, friendlyName) or ((vm.MainVm)DataContext).OnDragDrop(removedIdx, targetIdx), etc.

In this implementation, I did not use DataTemplates (for Header, FoldedHeader, etc.) and an ItemTemplateSelector. I use a standard list where elements are made visible or not by binding to the MyListElement properties: IsHidden, IsExtraGroupHeader, IsFolded, etc. For a first impression, see the pseudo XAML below.

Note that for making list items completely invisible when folded, we use the style of the list item, otherwise the item is still visible with a height of a few pixels which adds up for folded groups.

XML
< ListBox x:Name="myListBox1" ....
    ItemsSource="{Binding MyList}" 
    ScrollViewer.HorizontalScrollBarVisibility="Hidden"
    >

    <!--Using style to control visibility ListBoxItem, otherwise still visible height-->
    <ListBox.Resources>
       <Style TargetType="ListBoxItem">
         <Setter Property="Visibility" 
          Value="{Binding IsHidden, Converter={StaticResource Bool2NotVis}}" />
         <Setter Property="Focusable" Value="False"/>
   	  ....
       </Style>
    </ListBox.Resources>

    <ListBox.ItemTemplate>
      <DataTemplate DataType="{x:Type mylist:MyListElement}">
        <Grid ToolTip="{Binding Path=FullName}" >

          <StackPanel .... Orientation="Horizontal" Margin="-2"
             Visibility="{Binding IsExtraGroupHeader, Converter={StaticResource Bool2NotVis}}"     
          >
            <Image ....   Source = "{Binding Icon}" />
            <TextBlock ... Text="{Binding Path=FriendlyName}" />
          </StackPanel>

          <DockPanel 
            Visibility="{Binding IsExtraGroupHeader, Converter={StaticResource Bool2Vis}}">
            <Rectangle ... Stroke="SteelBlue"/>
            <TextBlock ... Foreground="SteelBlue"  Text="{Binding Path=FriendlyName}" />

            <StackPanel Orientation="Horizontal" ... 
                Visibility="{Binding Path=IsFolded, Converter={StaticResource Bool2Vis}  }"
            >
              <Ellipse Fill="SteelBlue" ... />
              <Ellipse Fill="SteelBlue" ... />
            </StackPanel>
	     
             <Rectangle .... Stroke="SteelBlue" />
          </DockPanel>

        </Grid>
    </DataTemplate>
</ListBox.ItemTemplate>

Discussion

Although this is more a trick/tip than a real article, I choose for an article to make this simple utility more broadly available. Enjoy if you like it.

 

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Netherlands Netherlands
Retired hobby programmer.

Comments and Discussions

 
-- There are no messages in this forum --