fix: fix identation, fix error theme in demo.

This commit is contained in:
rabbitism 2023-07-27 00:30:32 +08:00
parent 17fa10333a
commit 1c98ce4682
2 changed files with 191 additions and 186 deletions

View File

@ -112,10 +112,18 @@
</MultiBinding> </MultiBinding>
</Image.Source> </Image.Source>
</Image> </Image>
<TextBox VerticalAlignment="Center" Text="{Binding Name}" /> <TextBox
VerticalAlignment="Center"
Classes="Small"
Text="{Binding Name}">
<TextBox.Styles>
<Style Selector="DataValidationErrors">
<Setter Property="Theme" Value="{DynamicResource TooltipDataValidationErrors}" />
</Style>
</TextBox.Styles>
</TextBox>
</StackPanel> </StackPanel>
</DataTemplate> </DataTemplate>
</TreeDataGrid.Resources> </TreeDataGrid.Resources>
<TreeDataGrid.Styles> <TreeDataGrid.Styles>
<Style Selector="TreeDataGrid TreeDataGridRow:nth-child(2n)"> <Style Selector="TreeDataGrid TreeDataGridRow:nth-child(2n)">

View File

@ -171,219 +171,216 @@ public class FilesPageViewModel: ObservableObject
public class FileNodeViewModel: ObservableObject, IEditableObject public class FileNodeViewModel: ObservableObject, IEditableObject
{ {
private string _path; private string _path;
private string _name; private string _name;
private string? _undoName; private string? _undoName;
private long? _size; private long? _size;
private DateTimeOffset? _modified; private DateTimeOffset? _modified;
private FileSystemWatcher? _watcher; private FileSystemWatcher? _watcher;
private ObservableCollection<FileNodeViewModel>? _children; private ObservableCollection<FileNodeViewModel>? _children;
private bool _hasChildren = true; private bool _hasChildren = true;
private bool _isExpanded; private bool _isExpanded;
public FileNodeViewModel( public FileNodeViewModel( string path, bool isDirectory, bool isRoot = false)
string path, {
bool isDirectory, _path = path;
bool isRoot = false) _name = isRoot ? path : System.IO.Path.GetFileName(Path);
_isExpanded = isRoot;
IsDirectory = isDirectory;
HasChildren = isDirectory;
if (!isDirectory)
{ {
_path = path; var info = new FileInfo(path);
_name = isRoot ? path : System.IO.Path.GetFileName(Path); Size = info.Length;
_isExpanded = isRoot; Modified = info.LastWriteTimeUtc;
IsDirectory = isDirectory; }
HasChildren = isDirectory; }
if (!isDirectory) public string Path
{ {
var info = new FileInfo(path); get => _path;
Size = info.Length; private set => SetProperty(ref _path, value);
Modified = info.LastWriteTimeUtc; }
}
public string Name
{
get => _name;
private set => SetProperty(ref _name, value);
}
public long? Size
{
get => _size;
private set => SetProperty(ref _size, value);
}
public DateTimeOffset? Modified
{
get => _modified;
private set => SetProperty(ref _modified, value);
}
public bool HasChildren
{
get => _hasChildren;
private set => SetProperty(ref _hasChildren, value);
}
public bool IsExpanded
{
get => _isExpanded;
set => SetProperty(ref _isExpanded, value);
}
public bool IsChecked { get; set; }
public bool IsDirectory { get; }
public IReadOnlyList<FileNodeViewModel> Children => _children ??= LoadChildren();
private ObservableCollection<FileNodeViewModel> LoadChildren()
{
if (!IsDirectory)
{
throw new NotSupportedException();
} }
public string Path var options = new EnumerationOptions { IgnoreInaccessible = true };
var result = new ObservableCollection<FileNodeViewModel>();
foreach (var d in Directory.EnumerateDirectories(Path, "*", options))
{ {
get => _path; result.Add(new FileNodeViewModel(d, true));
private set => SetProperty(ref _path, value);
} }
public string Name foreach (var f in Directory.EnumerateFiles(Path, "*", options))
{ {
get => _name; result.Add(new FileNodeViewModel(f, false));
private set => SetProperty(ref _name, value);
} }
public long? Size _watcher = new FileSystemWatcher
{ {
get => _size; Path = Path,
private set => SetProperty(ref _size, value); NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite,
} };
public DateTimeOffset? Modified _watcher.Changed += OnChanged;
_watcher.Created += OnCreated;
_watcher.Deleted += OnDeleted;
_watcher.Renamed += OnRenamed;
_watcher.EnableRaisingEvents = true;
if (result.Count == 0)
HasChildren = false;
return result;
}
public static Comparison<FileNodeViewModel?> SortAscending<T>(Func<FileNodeViewModel, T> selector)
{
return (x, y) =>
{ {
get => _modified; if (x is null && y is null)
private set => SetProperty(ref _modified, value); return 0;
} else if (x is null)
return -1;
else if (y is null)
return 1;
if (x.IsDirectory == y.IsDirectory)
return Comparer<T>.Default.Compare(selector(x), selector(y));
else if (x.IsDirectory)
return -1;
else
return 1;
};
}
public bool HasChildren public static Comparison<FileNodeViewModel?> SortDescending<T>(Func<FileNodeViewModel, T> selector)
{
return (x, y) =>
{ {
get => _hasChildren; if (x is null && y is null)
private set => SetProperty(ref _hasChildren, value); return 0;
} else if (x is null)
return 1;
else if (y is null)
return -1;
if (x.IsDirectory == y.IsDirectory)
return Comparer<T>.Default.Compare(selector(y), selector(x));
else if (x.IsDirectory)
return -1;
else
return 1;
};
}
public bool IsExpanded void IEditableObject.BeginEdit() => _undoName = _name;
{ void IEditableObject.CancelEdit() => _name = _undoName!;
get => _isExpanded; void IEditableObject.EndEdit() => _undoName = null;
set => SetProperty(ref _isExpanded, value);
}
public bool IsChecked { get; set; } private void OnChanged(object sender, FileSystemEventArgs e)
public bool IsDirectory { get; } {
public IReadOnlyList<FileNodeViewModel> Children => _children ??= LoadChildren(); if (e.ChangeType == WatcherChangeTypes.Changed && File.Exists(e.FullPath))
private ObservableCollection<FileNodeViewModel> LoadChildren()
{
if (!IsDirectory)
{
throw new NotSupportedException();
}
var options = new EnumerationOptions { IgnoreInaccessible = true };
var result = new ObservableCollection<FileNodeViewModel>();
foreach (var d in Directory.EnumerateDirectories(Path, "*", options))
{
result.Add(new FileNodeViewModel(d, true));
}
foreach (var f in Directory.EnumerateFiles(Path, "*", options))
{
result.Add(new FileNodeViewModel(f, false));
}
_watcher = new FileSystemWatcher
{
Path = Path,
NotifyFilter = NotifyFilters.FileName | NotifyFilters.Size | NotifyFilters.LastWrite,
};
_watcher.Changed += OnChanged;
_watcher.Created += OnCreated;
_watcher.Deleted += OnDeleted;
_watcher.Renamed += OnRenamed;
_watcher.EnableRaisingEvents = true;
if (result.Count == 0)
HasChildren = false;
return result;
}
public static Comparison<FileNodeViewModel?> SortAscending<T>(Func<FileNodeViewModel, T> selector)
{
return (x, y) =>
{
if (x is null && y is null)
return 0;
else if (x is null)
return -1;
else if (y is null)
return 1;
if (x.IsDirectory == y.IsDirectory)
return Comparer<T>.Default.Compare(selector(x), selector(y));
else if (x.IsDirectory)
return -1;
else
return 1;
};
}
public static Comparison<FileNodeViewModel?> SortDescending<T>(Func<FileNodeViewModel, T> selector)
{
return (x, y) =>
{
if (x is null && y is null)
return 0;
else if (x is null)
return 1;
else if (y is null)
return -1;
if (x.IsDirectory == y.IsDirectory)
return Comparer<T>.Default.Compare(selector(y), selector(x));
else if (x.IsDirectory)
return -1;
else
return 1;
};
}
void IEditableObject.BeginEdit() => _undoName = _name;
void IEditableObject.CancelEdit() => _name = _undoName!;
void IEditableObject.EndEdit() => _undoName = null;
private void OnChanged(object sender, FileSystemEventArgs e)
{
if (e.ChangeType == WatcherChangeTypes.Changed && File.Exists(e.FullPath))
{
Dispatcher.UIThread.Post(() =>
{
foreach (var child in _children!)
{
if (child.Path == e.FullPath)
{
if (!child.IsDirectory)
{
var info = new FileInfo(e.FullPath);
child.Size = info.Length;
child.Modified = info.LastWriteTimeUtc;
}
break;
}
}
});
}
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
var node = new FileNodeViewModel(
e.FullPath,
File.GetAttributes(e.FullPath).HasFlag(FileAttributes.Directory));
_children!.Add(node);
});
}
private void OnDeleted(object sender, FileSystemEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
for (var i = 0; i < _children!.Count; ++i)
{
if (_children[i].Path == e.FullPath)
{
_children.RemoveAt(i);
System.Diagnostics.Debug.WriteLine($"Removed {e.FullPath}");
break;
}
}
});
}
private void OnRenamed(object sender, RenamedEventArgs e)
{ {
Dispatcher.UIThread.Post(() => Dispatcher.UIThread.Post(() =>
{ {
foreach (var child in _children!) foreach (var child in _children!)
{ {
if (child.Path == e.OldFullPath) if (child.Path == e.FullPath)
{ {
child.Path = e.FullPath; if (!child.IsDirectory)
child.Name = e.Name ?? string.Empty; {
var info = new FileInfo(e.FullPath);
child.Size = info.Length;
child.Modified = info.LastWriteTimeUtc;
}
break; break;
} }
} }
}); });
} }
}
private void OnCreated(object sender, FileSystemEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
var node = new FileNodeViewModel(
e.FullPath,
File.GetAttributes(e.FullPath).HasFlag(FileAttributes.Directory));
_children!.Add(node);
});
}
private void OnDeleted(object sender, FileSystemEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
for (var i = 0; i < _children!.Count; ++i)
{
if (_children[i].Path == e.FullPath)
{
_children.RemoveAt(i);
System.Diagnostics.Debug.WriteLine($"Removed {e.FullPath}");
break;
}
}
});
}
private void OnRenamed(object sender, RenamedEventArgs e)
{
Dispatcher.UIThread.Post(() =>
{
foreach (var child in _children!)
{
if (child.Path == e.OldFullPath)
{
child.Path = e.FullPath;
child.Name = e.Name ?? string.Empty;
break;
}
}
});
}
} }
internal static class ListExtensions internal static class ListExtensions