Frohman
Frohman

Reputation: 111

How to store and display multiple user-selected files

Alright, this is hard to put into clear words, but here I go:

In my current project I am trying to allow the user to select executable files (these are to be launched when my application launches). In addition, I want to allow the user to choose whether they want my application to close these launched executable files when it itself closes (a simple boolean option, one for each .exe).

I use an open file dialog to allow the user to select an executable, and all I need from it is the path (which I successfully obtain), however I need to display these files in a way which allows the user to select and remove them as well as set the aforementioned boolean for each one (as they so desire).

I can easily grab file names and icons (perfect to display to the user), but again I don't know what control will allow me to display this and include a boolean checkbox. Whatever control it is, it needs to allow the user to double click these entries (deleting them, in this case).

Now I assume I could use a dictionary to handle the data behind the scenes, with the string being the path to the file returned by the dialog and the bool being the bool I'd need to allow the user to change in the control... But I'm not sure if this is the best way of handling this data and I'm unsure of how I could populate the control with the information I can gather from the path (and allow the control to alter the boolean option).

I'm sorry if that didn't make sense, I'm finding it very, very difficult to put my predicament into words!

Thanks in advance if anyone can provide any assistance!

Upvotes: 1

Views: 505

Answers (4)

Richard
Richard

Reputation: 1142

The easiest way to do this in WPF is with Databinding. You can simply bind an ObservableCollection to a DataGrid and the rest just works.

To start with, you should create your own class to wrap the file name with a boolean field to indicate if it is selected or not.

class FileSelection
{
    public bool IsSelected { get; set; }
    public string FilePath { get; set; }
    public string FileName { get; set; }
    public string Picture { get; set; }
}

Add a DataGrid to your form like so:

 <DataGrid AutoGenerateColumns="False" Name="dataGrid1"
     BeginningEdit="dataGrid1_BeginningEdit">
        <DataGrid.Columns>
            <DataGridCheckBoxColumn Binding="{Binding IsSelected}"/>
            <DataGridTemplateColumn>
                <DataGridTemplateColumn.CellTemplate>
                    <DataTemplate>
                        <Image Width="25" Height="25" Source="{Binding Path=Picture}" />
                    </DataTemplate>
                </DataGridTemplateColumn.CellTemplate>
            </DataGridTemplateColumn>
            <DataGridTextColumn Binding="{Binding FileName}"/>
        </DataGrid.Columns>
    </DataGrid>

Then add code to your form to do the binding:

public partial class MainWindow : Window
{
    ObservableCollection<FileSelection> files;

    public MainWindow()
    {
        InitializeComponent();

        this.files = new ObservableCollection<FileSelection>();
        this.dataGrid1.ItemsSource = this.files;
    }

When you open your file dialog, simply add the returned path to the collection like so:

 var ofd = new OpenFileDialog();
 var result = ofd.ShowDialog();
 if (result == true)
 {
     var fs = new FileSelection { 
                FilePath = ofd.FileName, 
                FileName = System.IO.Path.GetFileNameWithoutExtension(ofd.FileName),
                Picture = @"[PATH TO IMAGE]",
                IsSelected = true };
     this.files.Add(fs);
 }

I tested this by opening a messageBox window to show the currently selected files like so:

var message = string.Join(Environment.NewLine, this.files.Where(f => f.IsSelected).Select(f => f.FilePath).ToArray());
MessageBox.Show(message);

Hope that does the trick!

UPDATE

I added another column to display an image using a DataGridTemplateColumn and changed the displayed text to only show the file name while retaining the full path in the data-bound list.

I also added an event handler to the DataGrid so that you can double-click a row to manipulate the selected file. You will need to add the following method to your code-behind class to use it.

private void dataGrid1_BeginningEdit(object sender, DataGridBeginningEditEventArgs e)
{
   var file = e.Row.DataContext as FileSelection;

   // Delete the file here...

   e.Cancel = true;
}

Note that the FileSelection bound to the clicked row is stored in the DataContext property of the Row. You need to set the Cancel property on the eventArgs parameter to true so that the row doesn't go into edit mode.

Upvotes: 2

Nuffin
Nuffin

Reputation: 3972

There is no builtin WPF Control which is capable of your specific needs (except the DataGrid, which is kinda difficult to handle when it comes to removing items via double click), but you can easily build your own one like this:

<Grid MouseLeftButtonDown="HandleClick">
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="Auto" />
        <ColumnDefinition />
    </Grid.ColumnDefinitions>
    <CheckBox IsChecked="{Binding YourCheckedProperty}" />
    <Grid Grid.Column="1">
        <!-- Here you can display your icon and filename -->
    </Grid>
</Grid>

For storing the data you should use a wrapper class:

public class FileWrapper
{
    public bool KillAtShutdown{get;set;}
    public string Path{get;set;}
    // your other properties
}

and store the wrappers in a List (if you use events and code behind stuff) or an ObservableCollection if you use bindings

Upvotes: 0

radarbob
radarbob

Reputation: 5101

Try a CheckBoxList if you're doing ASP.NET Or a LisBox if you're doing Windows forms

Upvotes: 0

Shekhar_Pro
Shekhar_Pro

Reputation: 18420

As i can get from your question you are trying to do this..

You want a Control which will show icons for files in a directory (What OpenFileDialog Box Do) but you want to have added functionality of some boolean field like check box for each shown icon.

Well There is no inbuilt control in the framework for your purpose. You can think of creating one yourself, you can use File and Directory related classes for this purpose.

Upvotes: 0

Related Questions