I'm making a simple file renaming program with a WPF UI. I take in a directory, read text into a grid, then apply changes. One of the parameters, however, which is the length of the file path, I would like to have updated on the fly as a user is typing in changes to their filename. Disclaimer: I'm very new to WPF and relatively new to C# (just trying to get back into programming, annoyingly, implementing WPF is more complicated than the C#, but I can't use WinForms for this one). I'm sure this is an INotifyPropertyChanged thing, though, from what I've seen online so far, there are quite a few ways to implement it-- so here I am. Thank you to all.
XAML
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:Files;assembly=FileCollection"
mc:Ignorable="d"
WindowStyle="SingleBorderWindow" WindowStartupLocation="CenterScreen"
Title="SLU Renamer" FontFamily="Segoe UI" Height="500" Width="1000" MinHeight="250" MinWidth="250" ResizeMode="CanResize">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="*" />
</Grid.RowDefinitions>
<Border BorderBrush="LightBlue" BorderThickness="1">
<StackPanel Grid.Row="0">
<Grid Height="25">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*" />
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Button Grid.Column="0" x:Name="BtnBrowse" Content="Browse" Click="BtnBrowse_Click" Background="AliceBlue" FontFamily="Segoe UI" FontSize="13" BorderBrush="LightBlue" BorderThickness="0"/>
<Button Grid.Column="3" x:Name="BtnApply" Content="Apply" Click="BtnApply_Click" Background="AliceBlue" FontFamily="Segoe UI" FontSize="13" BorderBrush="LightBlue" BorderThickness="0"/>
</Grid>
</StackPanel>
</Border>
<DockPanel Grid.Row="2">
<Grid x:Name="DataGridHolderGrid">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="727*"/>
<ColumnDefinition Width="33*"/>
</Grid.ColumnDefinitions>
<DataGrid Grid.Column="0" x:Name="DataGridFileNames" AutoGenerateColumns="False" ItemsSource="{Binding}" FontSize="13" FontFamily="Segoe UI Semibold" Background="White"
CanUserReorderColumns="True" CanUserSortColumns="True" CanUserResizeRows="False" CanUserResizeColumns="True" AlternatingRowBackground="LightBlue"
VerticalGridLinesBrush="DeepSkyBlue" HorizontalGridLinesBrush="DeepSkyBlue" BorderBrush="DeepSkyBlue" BorderThickness="0"
ScrollViewer.CanContentScroll="True" ScrollViewer.VerticalScrollBarVisibility="Auto" ScrollViewer.HorizontalScrollBarVisibility="Auto" Grid.ColumnSpan="2"
SourceUpdated="DataGridFileNames_SourceUpdated">
<DataGrid.Columns>
<DataGridTextColumn x:Name="OriginalFileNamesColumn" Header="Original Name" Width=".5*"
IsReadOnly="True" Binding="{Binding OriginalFileName}" />
<DataGridTextColumn x:Name="NewFileNamesColumn" Header="New Name" Width=".5*"
IsReadOnly="False" Binding="{Binding NewFileName, Mode=TwoWay}" />
<DataGridTextColumn x:Name="FileExensionColumn" Header="Ext." Width=".125*"
IsReadOnly="True" Binding="{Binding FileExtension}" />
<DataGridTextColumn x:Name="FinalFileNamesColumn" Header="File Path" Width=".75*"
IsReadOnly="True" Binding="{Binding NewPath}" />
<DataGridTextColumn x:Name="PathLengthColumn" Header="Length" Width=".125*"
IsReadOnly="True" Binding="{Binding PathLen, UpdateSourceTrigger=PropertyChanged}" />
</DataGrid.Columns>
</DataGrid>
</Grid>
</DockPanel>
</Grid>
</Window>
XAML.cs (Code Behind??)
using System;
using System.Linq;
using System.Windows;
using System.Windows.Data;
using IronXL;
using System.Windows.Forms;
using System.Collections.ObjectModel;
using System.IO;
namespace RenamerApp_3._0
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Microsoft.Win32.OpenFileDialog openFileDialog = new Microsoft.Win32.OpenFileDialog();
Microsoft.Win32.OpenFileDialog openExcelWkbkDialog = new Microsoft.Win32.OpenFileDialog();
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
//Dictionary<string, string> browseOptions = new Dictionary<string, string>();
public ObservableCollection<FileName> observableFileNames = new ObservableCollection<FileName>();
public MainWindow()
{
InitializeComponent();
InitDataGrid();
InitializeOpenFileDialog();
//DataGridFileNames.HeadersVisibility = ;
//InitializeComboBox();
}
private void BtnBrowse_Click(object sender, RoutedEventArgs e)
{
//OpenFileDialog();
OpenFolderDialog();
DataGridFileNames.Visibility = Visibility.Visible;
}
private void BtnApply_Click(object sender, RoutedEventArgs e)
{
foreach (var file in observableFileNames)
{
File.Move(file.OriginalPath + @"\" + file.OriginalFileName + file.FileExtension, file.NewPath + @"\" + file.NewFileName + file.FileExtension);
FileNameInit(file);
UpdateLen(file);
DataGridFileNames.Items.Refresh();
}
}
private void InitializeOpenFileDialog()
{
this.openFileDialog.Multiselect = true;
}
private void OpenFileDialog()
{
Nullable<bool> result = openFileDialog.ShowDialog();
if (result.HasValue && result.Value)
{
foreach (string filename in openFileDialog.FileNames)
{
FileName fileName = new FileName(filename);
observableFileNames.Add(fileName);
}
DataGridFileNames.DataContext = observableFileNames;
}
}
private void OpenFolderDialog()
{
DialogResult result = folderBrowserDialog.ShowDialog();
if (result == System.Windows.Forms.DialogResult.OK)
{
string path = folderBrowserDialog.SelectedPath;
DirectoryInfo directoryInfo = new DirectoryInfo(path);
FileInfo[] files = directoryInfo.GetFiles();
foreach (FileInfo file in files)
{
FileName fileName = new FileName(file);
observableFileNames.Add(fileName);
}
DataGridFileNames.DataContext = observableFileNames;
}
}
private void FileNameInit(FileName file)
{
file.OriginalFileName = file.NewFileName;
file.OriginalPath = file.NewPath;
}
private void InitDataGrid()
{
DataGridFileNames.Visibility = Visibility.Hidden;
}
private void DataGridFileNames_SourceUpdated(object sender, DataTransferEventArgs e)
{
UpdateLen(observableFileNames);
DataGridFileNames.Items.Refresh();
}
public void UpdateLen(ObservableCollection<FileName> observableFileNames)
{
int currentRowIndex = DataGridFileNames.Items.IndexOf(DataGridFileNames.CurrentItem);
FileName file = observableFileNames[currentRowIndex - 1];
file.PathLen = file.NewPath.Length + +@"\".Length + file.NewFileName.Length + file.FileExtension.Length;
}
public void UpdateLen(FileName file)
{
file.PathLen = file.NewPath.Length + +@"\".Length + file.NewFileName.Length + file.FileExtension.Length;
}
Data
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using IronXL;
namespace Files
{
public class FileName : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public FileInfo OriginalFile { get; set; }
public string FileExtension { get; set; }
public int PathLen { get; set; }
public string OriginalFileName { get; set; }
public string NewFileName { get; set; }
public string OriginalPath { get; set; }
public string NewPath { get; set; }
public FileName()
{
}
public FileName(string filename)
{
OriginalFile = new FileInfo(filename);
OriginalPath = NewPath = Path.GetDirectoryName(filename);
OriginalFileName = NewFileName = Path.GetFileNameWithoutExtension(filename);
FileExtension = Path.GetExtension(filename);
PathLen = filename.Length;
}
public FileName(FileInfo file)
{
OriginalFile = file;
OriginalPath = NewPath = OriginalFile.DirectoryName;
OriginalFileName = NewFileName = Path.GetFileNameWithoutExtension(OriginalFile.Name);
FileExtension = Path.GetExtension(OriginalFile.Name);
string path = OriginalFile.ToString();
PathLen = path.Length;
}
public string index { get; set; }
public FileName(WorkBook workbook, string index)
{
WorkSheet sheet = workbook.WorkSheets.First();
foreach (var cell in sheet[index])
{
string path = cell.ToString();
OriginalFile = new FileInfo(path);
OriginalPath = NewPath = OriginalFile.DirectoryName;
OriginalFileName = NewFileName = path;
PathLen = path.Length;
}
}
//String pathHolder;
//private void FileName_PropertyChanged(object sender, PropertyChangedEventArgs e)
//{
// pathHolder = NewPath + NewFileName + FileExtension;
// PathLen = pathHolder.Length;
//}
}
}
Updated Data Class
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.IO;
using System.Linq;
using System.Runtime.CompilerServices;
using IronXL;
namespace Files
{
public class FileName : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
public FileInfo OriginalFile { get; set; }
public string FileExtension { get; set; }
public string OriginalFileName { get; set; }
public string NewFileName { get; set; }
public string OriginalPath { get; set; }
private string _newPath;
public string NewPath
{
get { return _newPath; }
set
{
_newPath = NewPath;
PathLen = NewPath.Length + @"\".Length + NewFileName.Length + FileExtension.Length;
OnPropertyChanged();
}
}
private int _pathLen;
public int PathLen
{
get { return _pathLen; }
set
{
_pathLen = value;
OnPropertyChanged();
}
}
//public int PathLen { get; set; }
public FileName()
{
}
public FileName(string filename)
{
OriginalFile = new FileInfo(filename);
OriginalPath = NewPath = Path.GetDirectoryName(filename);
OriginalFileName = NewFileName = Path.GetFileNameWithoutExtension(filename);
FileExtension = Path.GetExtension(filename);
PathLen = filename.Length;
}
public FileName(FileInfo file)
{
OriginalFile = file;
OriginalPath = NewPath = OriginalFile.DirectoryName;
OriginalFileName = NewFileName = Path.GetFileNameWithoutExtension(OriginalFile.Name);
FileExtension = Path.GetExtension(OriginalFile.Name);
string path = OriginalFile.ToString();
PathLen = path.Length;
}
public string index { get; set; }
public FileName(WorkBook workbook, string index)
{
WorkSheet sheet = workbook.WorkSheets.First();
foreach (var cell in sheet[index])
{
string path = cell.ToString();
OriginalFile = new FileInfo(path);
OriginalPath = NewPath = OriginalFile.DirectoryName;
OriginalFileName = NewFileName = path;
PathLen = path.Length;
}
}
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
}
}