fix: fix identation, fix error theme in demo.
This commit is contained in:
parent
17fa10333a
commit
1c98ce4682
@ -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)">
|
||||||
|
@ -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
|
||||||
|
Loading…
x
Reference in New Issue
Block a user