Improve commands & add multiple selection feature

This commit is contained in:
azakhi
2018-09-13 17:34:16 +03:00
parent ac6943d73b
commit 32523787d2
23 changed files with 893 additions and 814 deletions

View File

@@ -191,6 +191,7 @@
<Compile Include="UserControls\ThemeComponentSelectionControl.xaml.cs">
<DependentUpon>ThemeComponentSelectionControl.xaml</DependentUpon>
</Compile>
<Compile Include="Views\AttachedProperties\SelectedItemsAttachedProperty.cs" />
<Compile Include="Utility\RoutedCommandHandler.cs" />
<Compile Include="Utility\RoutedCommandHandlers.cs" />
<Compile Include="ViewModels\AvalonDockWorkspaceViewModel.cs" />

View File

@@ -21,16 +21,6 @@ namespace Filtration.ViewModels
public ItemFilterBlockViewModelBase()
{
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand);
PasteBlockCommand = new RelayCommand(OnPasteBlockCommand);
AddBlockCommand = new RelayCommand(OnAddBlockCommand);
AddSectionCommand = new RelayCommand(OnAddSectionCommand);
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand);
_isVisible = true;
}
@@ -38,7 +28,17 @@ namespace Filtration.ViewModels
public virtual void Initialise(IItemFilterBlockBase itemfilterBlock, IItemFilterScriptViewModel itemFilterScriptViewModel)
{
BaseBlock = itemfilterBlock;
_parentScriptViewModel = itemFilterScriptViewModel;
_parentScriptViewModel = itemFilterScriptViewModel;
CopyBlockCommand = new RelayCommand(OnCopyBlockCommand);
PasteBlockCommand = new RelayCommand(OnPasteBlockCommand);
AddBlockCommand = new RelayCommand(OnAddBlockCommand);
AddSectionCommand = new RelayCommand(OnAddSectionCommand);
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => _parentScriptViewModel.CanModifyBlock(this));
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand);
}
public event EventHandler BlockBecameDirty;
@@ -46,15 +46,15 @@ namespace Filtration.ViewModels
public IItemFilterBlockBase BaseBlock { get; protected set; }
public IItemFilterScriptViewModel _parentScriptViewModel;
public RelayCommand CopyBlockCommand { get; }
public RelayCommand PasteBlockCommand { get; }
public RelayCommand AddBlockCommand { get; }
public RelayCommand AddSectionCommand { get; }
public RelayCommand DeleteBlockCommand { get; }
public RelayCommand MoveBlockUpCommand { get; }
public RelayCommand MoveBlockDownCommand { get; }
public RelayCommand MoveBlockToTopCommand { get; }
public RelayCommand MoveBlockToBottomCommand { get; }
public RelayCommand CopyBlockCommand { get; private set; }
public RelayCommand PasteBlockCommand { get; private set; }
public RelayCommand AddBlockCommand { get; private set; }
public RelayCommand AddSectionCommand { get; private set; }
public RelayCommand DeleteBlockCommand { get; private set; }
public RelayCommand MoveBlockUpCommand { get; private set; }
public RelayCommand MoveBlockDownCommand { get; private set; }
public RelayCommand MoveBlockToTopCommand { get; private set; }
public RelayCommand MoveBlockToBottomCommand { get; private set; }
public bool IsDirty
{

View File

@@ -10,17 +10,20 @@ namespace Filtration.ViewModels
IItemFilterCommentBlock ItemFilterCommentBlock { get; }
string Comment { get; }
bool IsExpanded { get; set; }
bool HasChild { get; set; }
bool HasVisibleChild { get; }
}
internal class ItemFilterCommentBlockViewModel : ItemFilterBlockViewModelBase, IItemFilterCommentBlockViewModel
{
private bool _isExpanded;
private bool _hasChild;
private int _childCount;
private int _visibleChildCount;
public ItemFilterCommentBlockViewModel()
{
_isExpanded = true;
_childCount = 0;
_visibleChildCount = 0;
ToggleSectionCommand = new RelayCommand(OnToggleSectionCommand);
}
@@ -92,16 +95,32 @@ namespace Filtration.ViewModels
}
}
public bool HasChild
public int ChildCount
{
get => _hasChild;
get => _childCount;
set
{
_hasChild = value;
_childCount = value;
RaisePropertyChanged();
}
}
public int VisibleChildCount
{
get => _visibleChildCount;
set
{
_visibleChildCount = value;
RaisePropertyChanged();
RaisePropertyChanged(nameof(HasVisibleChild));
}
}
public bool HasVisibleChild
{
get => (_visibleChildCount > 0);
}
private void OnToggleSectionCommand()
{
_parentScriptViewModel.ToggleSection(this);

File diff suppressed because it is too large Load Diff

View File

@@ -97,18 +97,18 @@ namespace Filtration.ViewModels
RedoCommand = new RelayCommand(OnRedoCommand, () => ActiveDocumentIsScript);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
MoveBlockUpCommand = new RelayCommand(OnMoveBlockUpCommand, () => ActiveDocumentIsScript && ActiveScriptHasSingleSelectedeBlock);
MoveBlockDownCommand = new RelayCommand(OnMoveBlockDownCommand, () => ActiveDocumentIsScript && ActiveScriptHasSingleSelectedeBlock);
MoveBlockToTopCommand = new RelayCommand(OnMoveBlockToTopCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock && ActiveScriptCanModifySelectedBlocks);
MoveBlockToBottomCommand = new RelayCommand(OnMoveBlockToBottomCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock && ActiveScriptCanModifySelectedBlocks);
AddBlockCommand = new RelayCommand(OnAddBlockCommand, () => ActiveDocumentIsScript);
AddSectionCommand = new RelayCommand(OnAddSectionCommand, () => ActiveDocumentIsScript);
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedBlock);
DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedEnabledBlock);
EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedDisabledBlock);
DisableSectionCommand = new RelayCommand(OnDisableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
EnableSectionCommand = new RelayCommand(OnEnableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
DeleteBlockCommand = new RelayCommand(OnDeleteBlockCommand, () => ActiveDocumentIsScript && ActiveScriptCanModifySelectedBlocks);
DisableBlockCommand = new RelayCommand(OnDisableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedEnabledBlock && ActiveScriptCanModifySelectedBlocks);
EnableBlockCommand = new RelayCommand(OnEnableBlockCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedDisabledBlock && ActiveScriptCanModifySelectedBlocks);
DisableSectionCommand = new RelayCommand(OnDisableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock && ActiveScriptCanModifySelectedBlocks);
EnableSectionCommand = new RelayCommand(OnEnableSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock && ActiveScriptCanModifySelectedBlocks);
ExpandSectionCommand = new RelayCommand(OnExpandSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
CollapseSectionCommand = new RelayCommand(OnCollapseSectionCommand, () => ActiveDocumentIsScript && ActiveScriptHasSelectedCommentBlock);
OpenAboutWindowCommand = new RelayCommand(OnOpenAboutWindowCommand);
@@ -329,7 +329,9 @@ namespace Filtration.ViewModels
public bool ActiveDocumentIsTheme => _avalonDockWorkspaceViewModel.ActiveDocument!= null && _avalonDockWorkspaceViewModel.ActiveDocument.IsTheme;
public bool ActiveScriptHasSelectedBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel != null;
public bool ActiveScriptHasSelectedBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.LastSelectedBlockViewModel != null;
public bool ActiveScriptHasSingleSelectedeBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModels.Count == 1;
public bool ActiveScriptHasSelectedEnabledBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.HasSelectedEnabledBlock();
@@ -337,6 +339,8 @@ namespace Filtration.ViewModels
public bool ActiveScriptHasSelectedCommentBlock => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.HasSelectedCommentBlock();
public bool ActiveScriptCanModifySelectedBlocks => AvalonDockWorkspaceViewModel.ActiveScriptViewModel.CanModifySelectedBlocks();
public bool ActiveThemeIsEditable => AvalonDockWorkspaceViewModel.ActiveThemeViewModel.IsMasterTheme;

View File

@@ -30,14 +30,14 @@ namespace Filtration.ViewModels.ToolPanes
{
switch (message.Notification)
{
case "SelectedBlockChanged":
case "LastSelectedBlockChanged":
{
OnSelectedBlockChanged(this, EventArgs.Empty);
OnLastSelectedBlockChanged(this, EventArgs.Empty);
break;
}
case "ActiveDocumentChanged":
{
OnSelectedBlockChanged(this, EventArgs.Empty);
OnLastSelectedBlockChanged(this, EventArgs.Empty);
break;
}
}
@@ -62,9 +62,9 @@ namespace Filtration.ViewModels.ToolPanes
PreviewText = string.Empty;
}
private void OnSelectedBlockChanged(object sender, EventArgs e)
private void OnLastSelectedBlockChanged(object sender, EventArgs e)
{
if (AvalonDockWorkspaceViewModel.ActiveScriptViewModel?.SelectedBlockViewModel == null)
if (AvalonDockWorkspaceViewModel.ActiveScriptViewModel?.LastSelectedBlockViewModel == null)
{
PreviewText = string.Empty;
return;
@@ -72,7 +72,7 @@ namespace Filtration.ViewModels.ToolPanes
PreviewText =
_itemFilterBlockTranslator.TranslateItemFilterBlockBaseToString(
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.SelectedBlockViewModel.BaseBlock);
AvalonDockWorkspaceViewModel.ActiveScriptViewModel.LastSelectedBlockViewModel.BaseBlock);
}
}
}

View File

@@ -0,0 +1,93 @@
using System.Collections;
using System.Collections.Specialized;
using System.Windows;
using System.Windows.Controls;
namespace Filtration.Views.AttachedProperties
{
public static class SelectedItemsAttachedProperty
{
public static readonly DependencyProperty SelectedItemsProperty =
DependencyProperty.RegisterAttached("SelectedItems", typeof(IList), typeof(SelectedItemsAttachedProperty),
new FrameworkPropertyMetadata(null, new PropertyChangedCallback(OnSelectedItemsChanged)));
public static IList GetSelectedItems(DependencyObject obj)
{
return (IList)obj.GetValue(SelectedItemsProperty);
}
public static void SetSelectedItems(DependencyObject obj, IList value)
{
obj.SetValue(SelectedItemsProperty, value);
}
private static void OnSelectedItemsChanged(DependencyObject d, DependencyPropertyChangedEventArgs e)
{
var listbox = d as ListBox;
if (listbox != null)
{
listbox.SelectedItems.Clear();
var selectedItems = e.NewValue as IList;
if (selectedItems != null)
{
foreach (var item in selectedItems)
{
listbox.SelectedItems.Add(item);
}
listbox.SelectionChanged += (s, ev) =>
{
if (null != ev.RemovedItems)
{
foreach (var item in ev.RemovedItems)
{
selectedItems.Remove(item);
}
}
if (null != ev.AddedItems)
{
foreach (var item in ev.AddedItems)
{
if (!selectedItems.Contains(item))
{
selectedItems.Add(item);
}
}
}
};
if (selectedItems is INotifyCollectionChanged)
{
(selectedItems as INotifyCollectionChanged).CollectionChanged += (s, ev) =>
{
// If this is the case, list requires re-adding all
if (ev.Action == NotifyCollectionChangedAction.Reset)
{
listbox.SelectedItems.Clear();
}
if (null != ev.OldItems)
{
foreach (var item in ev.OldItems)
{
listbox.SelectedItems.Remove(item);
}
}
if (null != ev.NewItems)
{
foreach (var item in ev.NewItems)
{
if (!listbox.SelectedItems.Contains(item))
{
listbox.SelectedItems.Add(item);
}
}
}
};
}
}
}
}
}
}

View File

@@ -89,7 +89,7 @@
</Grid.ColumnDefinitions>
<Label Grid.Column="0" VerticalAlignment="Center" MinWidth="150" Content="{Binding Header, Mode=OneWay}" />
<WrapPanel Grid.Column="1" HorizontalAlignment="Right" Visibility="{Binding HasChild, Converter={StaticResource BooleanVisibilityConverter}}">
<WrapPanel Grid.Column="1" HorizontalAlignment="Right" Visibility="{Binding HasVisibleChild, Converter={StaticResource BooleanVisibilityConverter}}">
<Button Command="{Binding ToggleSectionCommand}"
Width="25"
Height="25"

View File

@@ -61,7 +61,7 @@
ScrollViewer.HorizontalScrollBarVisibility="Disabled"
VirtualizingStackPanel.VirtualizationMode="Recycling"
attachedProperties:SelectingItemAttachedProperty.SelectingItem="{Binding CommentBlockBrowserBrowserSelectedBlockViewModel}"
SelectedItem="{Binding SelectedBlockViewModel}">
SelectionMode="Extended" attachedProperties:SelectedItemsAttachedProperty.SelectedItems="{Binding SelectedBlockViewModels}">
<!--ItemTemplateSelector="{StaticResource BlockTemplateSelector}"-->
<ListBox.InputBindings>
<KeyBinding Key="Delete" Command="{Binding DeleteBlockCommand}" />