Skip to content

Commit 5ad9a1c

Browse files
committed
Revert expand collapse to behavior, add quick-fix context menu. Closes #4028
1 parent 6ec32a6 commit 5ad9a1c

File tree

9 files changed

+218
-46
lines changed

9 files changed

+218
-46
lines changed
Lines changed: 35 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,35 @@
1+
using System.Windows;
2+
using System.Windows.Controls;
3+
using System.Windows.Interactivity;
4+
using GongSolutions.Wpf.DragDrop.Utilities;
5+
6+
namespace Rubberduck.UI.Controls
7+
{
8+
public class GroupItemExpandedBehavior : Behavior<DataGrid>
9+
{
10+
public object ExpandedState
11+
{
12+
get => GetValue(ExpandedStateProperty);
13+
set => SetValue(ExpandedStateProperty, value);
14+
}
15+
16+
public static readonly DependencyProperty ExpandedStateProperty =
17+
DependencyProperty.Register("ExpandedState", typeof(object), typeof(GroupItemExpandedBehavior), new UIPropertyMetadata(null, OnExpandedStateChanged));
18+
19+
private static void OnExpandedStateChanged(DependencyObject sender, DependencyPropertyChangedEventArgs e)
20+
{
21+
if (!(sender is GroupItemExpandedBehavior data) ||
22+
!(data.AssociatedObject is DataGrid grid) ||
23+
!grid.IsGrouping ||
24+
!(e.NewValue is bool))
25+
{
26+
return;
27+
}
28+
29+
foreach (var expander in grid.GetVisualDescendents<Expander>())
30+
{
31+
expander.IsExpanded = (bool)e.NewValue;
32+
}
33+
}
34+
}
35+
}

Rubberduck.Core/UI/Controls/GroupingGrid.xaml

Lines changed: 11 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -60,8 +60,7 @@
6060
<Setter Property="Template">
6161
<Setter.Value>
6262
<ControlTemplate>
63-
<Expander Background="WhiteSmoke" Foreground="Black" FontWeight="SemiBold"
64-
IsExpanded="{Binding IsExpanded, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:GroupingGrid}}}">
63+
<Expander Background="WhiteSmoke" Foreground="Black" FontWeight="SemiBold">
6564
<Expander.Header>
6665
<StackPanel Orientation="Horizontal">
6766
<TextBlock Margin="4"
@@ -108,7 +107,6 @@
108107
<Setter Property="HorizontalScrollBarVisibility" Value="Disabled" />
109108
<Setter Property="ItemContainerStyle" Value="{StaticResource PrettifyRow}" />
110109
<Setter Property="ColumnHeaderHeight" Value="22" />
111-
<Setter Property="SelectionMode" Value="Single" />
112110
</Style>
113111
</DataGrid.Style>
114112
<DataGrid.CellStyle>
@@ -117,7 +115,16 @@
117115
<Setter Property="Background" Value="Transparent" />
118116
<Setter Property="Padding" Value="0" />
119117
<Setter Property="VerticalContentAlignment" Value="Stretch" />
120-
<Setter Property="VerticalAlignment" Value="Center" />
118+
<Setter Property="VerticalAlignment" Value="Stretch" />
119+
<Setter Property="Template">
120+
<Setter.Value>
121+
<ControlTemplate TargetType="{x:Type DataGridCell}">
122+
<Grid Background="{TemplateBinding Background}">
123+
<ContentPresenter VerticalAlignment="Center" />
124+
</Grid>
125+
</ControlTemplate>
126+
</Setter.Value>
127+
</Setter>
121128
</Style>
122129
</DataGrid.CellStyle>
123130
</DataGrid>

Rubberduck.Core/UI/Controls/GroupingGrid.xaml.cs

Lines changed: 0 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -9,21 +9,12 @@ public partial class GroupingGrid
99
public static readonly DependencyProperty ShowGroupingItemCountProperty =
1010
DependencyProperty.Register("ShowGroupingItemCount", typeof (bool), typeof(GroupingGrid));
1111

12-
public static readonly DependencyProperty IsExpandedProperty =
13-
DependencyProperty.Register("IsExpanded", typeof(bool), typeof(GroupingGrid));
14-
1512
public bool ShowGroupingItemCount
1613
{
1714
get => (bool) GetValue(ShowGroupingItemCountProperty);
1815
set => SetValue(ShowGroupingItemCountProperty, value);
1916
}
2017

21-
public bool IsExpanded
22-
{
23-
get => (bool)GetValue(IsExpandedProperty);
24-
set => SetValue(IsExpandedProperty, value);
25-
}
26-
2718
public GroupingGrid()
2819
{
2920
InitializeComponent();

Rubberduck.Core/UI/Inspections/InspectionResultsControl.xaml

Lines changed: 39 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -6,6 +6,7 @@
66
xmlns:codeInspections="clr-namespace:Rubberduck.UI.Inspections"
77
xmlns:controls="clr-namespace:Rubberduck.UI.Controls"
88
xmlns:abstract1="clr-namespace:Rubberduck.Parsing.Inspections.Abstract;assembly=Rubberduck.Parsing"
9+
xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
910
ResxExtension.DefaultResxName="Rubberduck.Resources.RubberduckUI"
1011
Language="{UICulture}"
1112
mc:Ignorable="d"
@@ -19,6 +20,7 @@
1920

2021
<codeInspections:InspectionSeverityImageSourceConverter x:Key="SeverityIconConverter" />
2122
<codeInspections:InspectionImageSourceConverter x:Key="InspectionIconConverter" />
23+
<codeInspections:QuickFixImageSourceConverter x:Key="QuickFixIconConverter" />
2224

2325
<Style x:Key="IconMargin" TargetType="Image">
2426
<Setter Property="Margin" Value="4" />
@@ -46,11 +48,6 @@
4648
<Setter Property="Height" Value="16"/>
4749
<Setter Property="Width" Value="16" />
4850
</Style>
49-
50-
<Style TargetType="MenuItem">
51-
<Setter Property="VerticalAlignment" Value="Center"/>
52-
</Style>
53-
5451
</ResourceDictionary>
5552
</UserControl.Resources>
5653

@@ -94,7 +91,12 @@
9491
</MenuItem.Icon>
9592
<MenuItem.ItemContainerStyle>
9693
<Style TargetType="{x:Type MenuItem}">
97-
<Setter Property="Command" Value="{Binding Path=DataContext.QuickFixCommand, RelativeSource={RelativeSource FindAncestor, AncestorType=Menu, AncestorLevel=1}}" />
94+
<Setter Property="Icon">
95+
<Setter.Value>
96+
<Image Source="{Binding Fix, Converter={StaticResource QuickFixIconConverter}}" />
97+
</Setter.Value>
98+
</Setter>
99+
<Setter Property="Command" Value="{Binding Command}" />
98100
<Setter Property="CommandParameter" Value="{Binding Fix}" />
99101
<Setter Property="Header" Value="{Binding Description}" />
100102
<Setter Property="Background" Value="Transparent"></Setter>
@@ -192,10 +194,18 @@
192194
Grid.Row="1"
193195
ShowGroupingItemCount="True"
194196
SelectedItem="{Binding SelectedItem}"
195-
IsExpanded="{Binding IsExpanded, NotifyOnSourceUpdated=True}"
197+
SelectionUnit="FullRow"
196198
ItemsSource="{Binding Results, NotifyOnSourceUpdated=True}"
197-
VirtualizingPanel.IsVirtualizingWhenGrouping="True">
198-
<DataGrid.Columns>
199+
VirtualizingPanel.IsVirtualizingWhenGrouping="False">
200+
<DataGrid.RowDetailsTemplate>
201+
<DataTemplate>
202+
<Grid>
203+
<Rectangle Fill="Transparent" />
204+
<GridViewRowPresenter/>
205+
</Grid>
206+
</DataTemplate>
207+
</DataGrid.RowDetailsTemplate>
208+
<DataGrid.Columns>
199209
<DataGridTemplateColumn Header="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=CodeInspectionResults_Type}">
200210
<DataGridTemplateColumn.CellTemplate>
201211
<DataTemplate DataType="abstract1:IInspectionResult">
@@ -206,6 +216,26 @@
206216
<DataGridTextColumn Header="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=CodeInspectionResults_Issue}" Binding="{Binding Description, Mode=OneTime}" />
207217
<DataGridTextColumn Header="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=CodeInspectionResults_Location}" Binding="{Binding QualifiedSelection.QualifiedName, Mode=OneTime}" />
208218
</DataGrid.Columns>
219+
<DataGrid.ContextMenu>
220+
<ContextMenu ItemsSource="{Binding PlacementTarget.DataContext.QuickFixes, RelativeSource={RelativeSource Self}}">
221+
<ContextMenu.Resources>
222+
<Style TargetType="{x:Type MenuItem}">
223+
<Setter Property="Icon">
224+
<Setter.Value>
225+
<Image Source="{Binding Fix, Converter={StaticResource QuickFixIconConverter}}" />
226+
</Setter.Value>
227+
</Setter>
228+
<Setter Property="Command" Value="{Binding Command}" />
229+
<Setter Property="CommandParameter" Value="{Binding Fix}" />
230+
<Setter Property="Header" Value="{Binding Description}" />
231+
<Setter Property="Background" Value="Transparent"></Setter>
232+
</Style>
233+
</ContextMenu.Resources>
234+
</ContextMenu>
235+
</DataGrid.ContextMenu>
236+
<i:Interaction.Behaviors>
237+
<controls:GroupItemExpandedBehavior ExpandedState="{Binding ExpandedState, Mode=TwoWay}" />
238+
</i:Interaction.Behaviors>
209239
</controls:GroupingGrid>
210240

211241
<controls:EmptyUIRefresh Grid.Row="1" Visibility="{Binding Unparsed, Converter={StaticResource BoolToVisibility}}" />

Rubberduck.Core/UI/Inspections/InspectionResultsViewModel.cs

Lines changed: 24 additions & 23 deletions
Original file line numberDiff line numberDiff line change
@@ -10,6 +10,7 @@
1010
using System.Threading.Tasks;
1111
using System.Windows;
1212
using System.Windows.Data;
13+
using System.Windows.Input;
1314
using NLog;
1415
using Rubberduck.Common;
1516
using Rubberduck.Interaction.Navigation;
@@ -49,9 +50,11 @@ public class DisplayQuickFix
4950
{
5051
public IQuickFix Fix { get; }
5152
public string Description { get; }
53+
public ICommand Command { get; }
5254

53-
public DisplayQuickFix(IQuickFix fix, IInspectionResult result)
55+
public DisplayQuickFix(IQuickFix fix, IInspectionResult result, ICommand command)
5456
{
57+
Command = command;
5558
Fix = fix;
5659
Description = fix.Description(result);
5760
}
@@ -119,10 +122,12 @@ public InspectionResultsViewModel(
119122
// todo: remove I/O work in constructor
120123
_runInspectionsOnReparse = _configService.LoadConfiguration().UserSettings.CodeInspectionSettings.RunInspectionsOnSuccessfulParse;
121124

122-
var results = CollectionViewSource.GetDefaultView(_results) as ListCollectionView;
123-
results.Filter = inspection => InspectionFilter((IInspectionResult)inspection);
124-
results.CustomSort = this;
125-
Results = results;
125+
if (CollectionViewSource.GetDefaultView(_results) is ListCollectionView results)
126+
{
127+
results.Filter = inspection => InspectionFilter((IInspectionResult)inspection);
128+
results.CustomSort = this;
129+
Results = results;
130+
}
126131

127132
OnPropertyChanged(nameof(Results));
128133
Grouping = InspectionResultGrouping.Type;
@@ -147,7 +152,7 @@ private void _configService_SettingsChanged(object sender, ConfigurationChangedE
147152
_runInspectionsOnReparse = e.RunInspectionsOnReparse;
148153
}
149154

150-
private ObservableCollection<IInspectionResult> _results = new ObservableCollection<IInspectionResult>();
155+
private readonly ObservableCollection<IInspectionResult> _results = new ObservableCollection<IInspectionResult>();
151156

152157
public ICollectionView Results { get; }
153158

@@ -205,7 +210,7 @@ public IEnumerable<DisplayQuickFix> QuickFixes
205210
}
206211

207212
return _quickFixProvider.QuickFixes(SelectedItem as IInspectionResult)
208-
.Select(fix => new DisplayQuickFix(fix, (IInspectionResult) _selectedItem));
213+
.Select(fix => new DisplayQuickFix(fix, (IInspectionResult)_selectedItem, QuickFixCommand));
209214
}
210215
}
211216

@@ -287,12 +292,12 @@ private bool InspectionFilter(IInspectionResult result)
287292

288293
private void ExecuteCollapseAll(object parameter)
289294
{
290-
IsExpanded = false;
295+
ExpandedState = false;
291296
}
292297

293298
private void ExecuteExpandAll(object parameter)
294299
{
295-
IsExpanded = true;
300+
ExpandedState = true;
296301
}
297302

298303
private void OpenSettings(object param)
@@ -343,7 +348,7 @@ public bool Unparsed
343348
}
344349

345350
private bool _expanded;
346-
public bool IsExpanded
351+
public bool ExpandedState
347352
{
348353
get => _expanded;
349354
set
@@ -457,8 +462,7 @@ private void ExecuteQuickFixCommand(object parameter)
457462

458463
private bool CanExecuteQuickFixCommand(object parameter)
459464
{
460-
var quickFix = parameter as IQuickFix;
461-
return !IsBusy && quickFix != null && _state.Status == ParserState.Ready;
465+
return !IsBusy && parameter is IQuickFix && _state.Status == ParserState.Ready;
462466
}
463467

464468
private bool _canExecuteQuickFixInProcedure;
@@ -567,8 +571,7 @@ private void ExecuteQuickFixInProjectCommand(object parameter)
567571
return;
568572
}
569573

570-
var selectedResult = SelectedItem as IInspectionResult;
571-
if (selectedResult == null)
574+
if (!(SelectedItem is IInspectionResult selectedResult))
572575
{
573576
return;
574577
}
@@ -584,24 +587,22 @@ private void ExecuteQuickFixInAllProjectsCommand(object parameter)
584587
return;
585588
}
586589

587-
var selectedResult = SelectedItem as IInspectionResult;
588-
if (selectedResult == null)
590+
if (!(SelectedItem is IInspectionResult selectedResult))
589591
{
590592
return;
591593
}
592594

593595
_quickFixProvider.FixAll(_defaultFix, selectedResult.Inspection.GetType(), Results.OfType<IInspectionResult>());
594596
}
595597

596-
// TODO - these should be localized.
597598
private static readonly List<(string Name, hAlignment alignment)> ResultColumns = new List<(string Name, hAlignment alignment)>
598599
{
599-
("Type", hAlignment.Left),
600-
("Project", hAlignment.Left),
601-
("Component", hAlignment.Left),
602-
("Issue", hAlignment.Left),
603-
("Line", hAlignment.Right),
604-
("Column", hAlignment.Right)
600+
(Resources.Inspections.InspectionsUI.ExportColumnHeader_Type, hAlignment.Left),
601+
(Resources.Inspections.InspectionsUI.ExportColumnHeader_Project, hAlignment.Left),
602+
(Resources.Inspections.InspectionsUI.ExportColumnHeader_Component, hAlignment.Left),
603+
(Resources.Inspections.InspectionsUI.ExportColumnHeader_Issue, hAlignment.Left),
604+
(Resources.Inspections.InspectionsUI.ExportColumnHeader_Line, hAlignment.Right),
605+
(Resources.Inspections.InspectionsUI.ExportColumnHeader_Column, hAlignment.Right)
605606
};
606607

607608
private static readonly ColumnInfo[] ColumnInformation = ResultColumns.Select(column => new ColumnInfo(column.Name, column.alignment)).ToArray();
Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
using System;
2+
using System.Globalization;
3+
using System.Windows.Media;
4+
using Rubberduck.Resources.Inspections;
5+
using ImageSourceConverter = Rubberduck.UI.Converters.ImageSourceConverter;
6+
7+
namespace Rubberduck.UI.Inspections
8+
{
9+
public class QuickFixImageSourceConverter : ImageSourceConverter
10+
{
11+
private static readonly ImageSource IgnoreOnceIcon = ToImageSource(InspectionsUI.ignore_once);
12+
13+
public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
14+
{
15+
if (value != null && value.GetType().Name.Equals("IgnoreOnceQuickFix"))
16+
{
17+
return IgnoreOnceIcon;
18+
}
19+
20+
return null;
21+
}
22+
}
23+
}
Loading

0 commit comments

Comments
 (0)