How do you populate a WPF DataGrid with multi-selected file names for editing?

300 views Asked by At

I'm trying to create a very simple batch file renamer app in WPF. Implementation in WinForms was easy enough, but here, I feel like I've attempted soo many different implementations. I'm very new to WPF and am very much a novice in C#.

Simply, I want to read in files into a list or a class or however is recommended to implement. Bind that to the Datagrid, read the editable file names back into the list or list class... whatever.

I've wasted so much time on this and will literally pay someone to help at this point.

So sorry if this has been asked-- everything I've seen on here looks cool and all, but just has not worked in my scenario.

Many thanks

XAML

<Window x:Class="RenamerApp_3._0.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:FileInfo;assembly=FileCollection"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">

    <Grid>
        <StackPanel>
            <Grid>
                <Grid.ColumnDefinitions>
                    <ColumnDefinition Width="*" />
                    <ColumnDefinition Width="8*" />
                    <ColumnDefinition Width="*" />
                </Grid.ColumnDefinitions>

                <Button Grid.Column="0" x:Name="BtnBrowse" Content="Browse" Click="BtnBrowse_Click" />
                <TextBox Grid.Column="1" x:Name="TxtbxActiveDir" />
                <Button Grid.Column="2" x:Name="BtnApply" Content="Apply" />
            </Grid>
            <DataGrid x:Name="DataGridFileNames" ItemsSource="{Binding FileCollection}">
                <DataGrid.Columns>
                    <DataGridTextColumn x:Name="OriginalFileNamesColumn" Header="Original" Width="*" 
                                        IsReadOnly="True" />
                    <DataGridTextColumn x:Name="NewFileNamescolumn" Header="New" Width="*"
                                        IsReadOnly="False" />
                </DataGrid.Columns>
            </DataGrid>
        </StackPanel>
    </Grid>
</Window>

Code Behind

namespace RenamerApp_3._0
{
    /// <summary>
    /// Interaction logic for MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        OpenFileDialog dialog = new OpenFileDialog();

        public MainWindow()
        {
            InitializeComponent();
            InitializeOpenFileDialog();
        }

        private void BtnBrowse_Click(object sender, RoutedEventArgs e)
        {
            Nullable<bool> result = dialog.ShowDialog();
            if (result.HasValue && result.Value)
            {
                List<string> fileNames = dialog.FileNames.ToList();
                FileName.FileCollection collection = new FileName.FileCollection(fileNames);
                DataGridFileNames.DataContext = collection;
            }
        }

        private void InitializeOpenFileDialog()
        {
            this.dialog.Multiselect = true;
        }
    }
}

FileInfo Class

namespace FileInfo
{
    public class FileName
    {
        public string originalFileName { get; set; }
        public string newFileName { get; set; }

        public FileName()
        {
        }

        public class FileCollection : List<FileName>, INotifyPropertyChanged
        {
            public event PropertyChangedEventHandler PropertyChanged;

            public FileCollection(List<string> fileNames)
            {
                foreach (var item in fileNames)
                {
                    this.Add(new FileName() { originalFileName = item, newFileName = item });
                }
            }
        }
    }
}
1

There are 1 answers

0
Byoung Sam Moon On

XAML

<DataGrid x:Name="DataGridFileNames" ItemsSource="{Binding}" AutoGenerateColumns="False" >
    <DataGrid.Columns>
        <DataGridTextColumn x:Name="OriginalFileNamesColumn" Header="Original" Width="*"  Binding="{Binding originalFileName}" IsReadOnly="True" />
        <DataGridTextColumn x:Name="NewFileNamescolumn" Header="New" Width="*" Binding="{Binding newFileName}" IsReadOnly="False" />
    </DataGrid.Columns>
</DataGrid>

when collection assinged to DataContext, ItemsSource use just Binding. not Binding path. DataGridTextColumn need to add Binding to data object member.

FileName class

public class FileName
{
    public string originalFileName { get; set; }
    public string newFileName { get; set; }
}

Do not need to List<>, INotifyPropertyChanged. ObservableCollection is easy way to 2 way binding.

MainWindow

public partial class MainWindow : Window
{
    OpenFileDialog dialog = new OpenFileDialog();

    public ObservableCollection<FileName> fileNames = new ObservableCollection<FileName>();

    public MainWindow()
    {
        InitializeComponent();
        InitializeOpenFileDialog();
    }

    private void BtnBrowse_Click(object sender, RoutedEventArgs e)
    {
        Nullable<bool> result = dialog.ShowDialog();
        if (result.HasValue && result.Value)
        {
            foreach(string filename in dialog.FileNames)
            {
                FileName fileName = new FileName() { originalFileName = filename };
                fileNames.Add(fileName);
            }

            DataGridFileNames.DataContext = fileNames;
        }
    }

    private void InitializeOpenFileDialog()
    {
        this.dialog.Multiselect = true;
    }
}