Skip to content

Commit e7b7b92

Browse files
committed
Stop initializing commands lazily so that CanExecute binds correctly, styling tweaks.
1 parent 0f527e5 commit e7b7b92

File tree

2 files changed

+104
-126
lines changed

2 files changed

+104
-126
lines changed

Rubberduck.Core/UI/ToDoItems/ToDoExplorerControl.xaml

Lines changed: 28 additions & 14 deletions
Original file line numberDiff line numberDiff line change
@@ -223,9 +223,15 @@
223223
</Style.Triggers>
224224
</Style>
225225

226-
<Style TargetType="Image">
227-
<Setter Property="Height" Value="16"/>
226+
<Style x:Key="ToolbarImageOpacity" TargetType="Image" >
227+
<Setter Property="Height" Value="16" />
228228
<Setter Property="Width" Value="16" />
229+
<Setter Property="Margin" Value="2,0,2,0" />
230+
<Style.Triggers>
231+
<Trigger Property="IsEnabled" Value="False">
232+
<Setter Property="Opacity" Value="0.3" />
233+
</Trigger>
234+
</Style.Triggers>
229235
</Style>
230236
</UserControl.Resources>
231237

@@ -245,14 +251,21 @@
245251
<Setter Property="Margin" Value="2" />
246252
<Setter Property="BorderBrush" Value="{x:Static SystemColors.ActiveBorderBrush}" />
247253
</Style>
254+
<Style TargetType="Image">
255+
<Setter Property="Height" Value="16" />
256+
</Style>
248257
</ToolBar.Resources>
249-
<Button ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=Refresh}" Command="{Binding RefreshCommand, Mode=OneWay}" BorderThickness="0" Background="Transparent">
250-
<Image Source="{StaticResource RefreshImage}" />
258+
259+
<Button ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=Refresh}" Command="{Binding RefreshCommand}">
260+
<Image Source="{StaticResource RefreshImage}" Style="{StaticResource ToolbarImageOpacity}"/>
251261
</Button>
262+
252263
<Separator />
253-
<Button ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=Remove}" Command="{Binding RemoveCommand}" BorderThickness="0" Background="Transparent">
254-
<Image Source="{StaticResource DeleteImage}" />
264+
265+
<Button ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=Remove}" Command="{Binding RemoveCommand}">
266+
<Image Source="{StaticResource DeleteImage}" Style="{StaticResource ToolbarImageOpacity}" />
255267
</Button>
268+
256269
<Separator />
257270

258271
<Label Content="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=GroupingGrid_GroupingStyle}" VerticalContentAlignment="Center" />
@@ -271,26 +284,26 @@
271284

272285
<Separator />
273286

274-
<Button Name="CollapseAll" Command="{Binding CollapseAllCommand}" Margin="2"
287+
<Button Name="CollapseAll" Command="{Binding CollapseAllCommand}"
275288
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=InspectionResults_CollapseAll}">
276-
<Image Source="{StaticResource CollapseAllImage}" />
289+
<Image Source="{StaticResource CollapseAllImage}" Style="{StaticResource ToolbarImageOpacity}" />
277290
</Button>
278291

279-
<Button Name="ExpandAll" Command="{Binding ExpandAllCommand}" Margin="2"
292+
<Button Name="ExpandAll" Command="{Binding ExpandAllCommand}"
280293
ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=InspectionResults_ExpandAll}">
281-
<Image Source="{StaticResource ExpandAllImage}" />
294+
<Image Source="{StaticResource ExpandAllImage}" Style="{StaticResource ToolbarImageOpacity}" />
282295
</Button>
283296

284297
<Separator />
285298
<Button Command="{Binding CopyResultsCommand}">
286-
<Image Height="16" Source="{StaticResource CopyResultsImage}" />
299+
<Image Source="{StaticResource CopyResultsImage}" Style="{StaticResource ToolbarImageOpacity}" />
287300
<Button.ToolTip>
288301
<TextBlock Text="{Resx ResxName=Rubberduck.Resources.ToDoExplorer.ToDoExplorerUI, Key=ToDoExplorer_CopyToolTip}" />
289302
</Button.ToolTip>
290303
</Button>
291304
<Separator />
292-
<Button ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=Settings}" Command="{Binding OpenTodoSettings}" BorderThickness="0" Background="Transparent">
293-
<Image Source="{StaticResource SettingsImage}" />
305+
<Button ToolTip="{Resx ResxName=Rubberduck.Resources.RubberduckUI, Key=Settings}" Command="{Binding OpenTodoSettingsCommand}">
306+
<Image Source="{StaticResource SettingsImage}" Style="{StaticResource ToolbarImageOpacity}" />
294307
</Button>
295308
</ToolBar>
296309
</ToolBarTray>
@@ -299,7 +312,8 @@
299312
ShowGroupingItemCount="True"
300313
ItemsSource="{Binding Items, NotifyOnSourceUpdated=True}"
301314
SelectedItem="{Binding SelectedItem}"
302-
SelectionUnit="FullRow">
315+
SelectionUnit="FullRow"
316+
InitialExpandedState="True">
303317
<controls:GroupingGrid.Columns>
304318

305319
<DataGridTextColumn Header="{Resx ResxName=Rubberduck.Resources.ToDoExplorer.ToDoExplorerUI, Key=TodoExplorer_Description}" Binding="{Binding Description, Mode=OneTime}" Width="*"/>

Rubberduck.Core/UI/ToDoItems/ToDoExplorerViewModel.cs

Lines changed: 76 additions & 112 deletions
Original file line numberDiff line numberDiff line change
@@ -49,9 +49,12 @@ public ToDoExplorerViewModel(
4949
_uiDispatcher = uiDispatcher;
5050
_state.StateChanged += HandleStateChanged;
5151

52-
_navigateCommand = new Lazy<NavigateCommand>(() => new NavigateCommand(selectionService));
52+
NavigateCommand = new NavigateCommand(selectionService);
53+
RemoveCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteRemoveCommand, CanExecuteRemoveCommand);
5354
CollapseAllCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteCollapseAll);
5455
ExpandAllCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteExpandAll);
56+
CopyResultsCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteCopyResultsCommand, CanExecuteCopyResultsCommand);
57+
OpenTodoSettingsCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), ExecuteOpenTodoSettingsCommand);
5558

5659
Items = CollectionViewSource.GetDefaultView(_items);
5760
OnPropertyChanged(nameof(Items));
@@ -98,36 +101,17 @@ public bool ExpandedState
98101
}
99102
}
100103

101-
private CommandBase _refreshCommand;
102-
public CommandBase RefreshCommand
104+
private ToDoItem _selectedItem;
105+
public INavigateSource SelectedItem
103106
{
104-
get
107+
get => _selectedItem;
108+
set
105109
{
106-
if (_refreshCommand != null)
107-
{
108-
return _refreshCommand;
109-
}
110-
return _refreshCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), _ =>
111-
{
112-
_state.OnParseRequested(this);
113-
},
114-
_ => _state.IsDirty());
110+
_selectedItem = value as ToDoItem;
111+
OnPropertyChanged();
115112
}
116113
}
117114

118-
public CommandBase CollapseAllCommand { get; }
119-
public CommandBase ExpandAllCommand { get; }
120-
121-
private void ExecuteCollapseAll(object parameter)
122-
{
123-
ExpandedState = false;
124-
}
125-
126-
private void ExecuteExpandAll(object parameter)
127-
{
128-
ExpandedState = true;
129-
}
130-
131115
private void HandleStateChanged(object sender, EventArgs e)
132116
{
133117
if (_state.Status != ParserState.ResolvedDeclarations)
@@ -145,119 +129,99 @@ private void HandleStateChanged(object sender, EventArgs e)
145129
});
146130
}
147131

148-
private ToDoItem _selectedItem;
149-
public INavigateSource SelectedItem
132+
public INavigateCommand NavigateCommand { get; }
133+
134+
public ReparseCommand RefreshCommand { get; set; }
135+
136+
public CommandBase RemoveCommand { get; }
137+
138+
public CommandBase CollapseAllCommand { get; }
139+
140+
public CommandBase ExpandAllCommand { get; }
141+
142+
public CommandBase CopyResultsCommand { get; }
143+
144+
public CommandBase OpenTodoSettingsCommand { get; }
145+
146+
private void ExecuteCollapseAll(object parameter)
150147
{
151-
get => _selectedItem;
152-
set
153-
{
154-
_selectedItem = value as ToDoItem;
155-
OnPropertyChanged();
156-
}
148+
ExpandedState = false;
157149
}
158150

159-
private CommandBase _removeCommand;
160-
public CommandBase RemoveCommand
151+
private void ExecuteExpandAll(object parameter)
161152
{
162-
get
163-
{
164-
if (_removeCommand != null)
165-
{
166-
return _removeCommand;
167-
}
168-
return _removeCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), _ =>
169-
{
170-
if (_selectedItem == null)
171-
{
172-
return;
173-
}
153+
ExpandedState = true;
154+
}
155+
156+
private bool CanExecuteRemoveCommand(object obj) => SelectedItem != null && RefreshCommand.CanExecute(obj);
174157

175-
var component = _state.ProjectsProvider.Component(_selectedItem.Selection.QualifiedName);
176-
using (var module = component.CodeModule)
177-
{
178-
var oldContent = module.GetLines(_selectedItem.Selection.Selection.StartLine, 1);
179-
var newContent = oldContent.Remove(_selectedItem.Selection.Selection.StartColumn - 1);
158+
private void ExecuteRemoveCommand(object obj)
159+
{
160+
if (!CanExecuteRemoveCommand(obj))
161+
{
162+
return;
163+
}
180164

181-
module.ReplaceLine(_selectedItem.Selection.Selection.StartLine, newContent);
182-
}
165+
var component = _state.ProjectsProvider.Component(_selectedItem.Selection.QualifiedName);
166+
using (var module = component.CodeModule)
167+
{
168+
var oldContent = module.GetLines(_selectedItem.Selection.Selection.StartLine, 1);
169+
var newContent = oldContent.Remove(_selectedItem.Selection.Selection.StartColumn - 1);
183170

184-
RefreshCommand.Execute(null);
185-
}
186-
);
171+
module.ReplaceLine(_selectedItem.Selection.Selection.StartLine, newContent);
187172
}
173+
174+
RefreshCommand.Execute(null);
188175
}
189176

190-
private CommandBase _copyResultsCommand;
191-
public CommandBase CopyResultsCommand
177+
private bool CanExecuteCopyResultsCommand(object obj) => _items.Any();
178+
179+
public void ExecuteCopyResultsCommand(object obj)
192180
{
193-
get
181+
const string xmlSpreadsheetDataFormat = "XML Spreadsheet";
182+
if (!CanExecuteCopyResultsCommand(obj))
194183
{
195-
if (_copyResultsCommand != null)
196-
{
197-
return _copyResultsCommand;
198-
}
199-
return _copyResultsCommand = new DelegateCommand(LogManager.GetCurrentClassLogger(), _ =>
200-
{
201-
const string xmlSpreadsheetDataFormat = "XML Spreadsheet";
202-
if (_items == null)
203-
{
204-
return;
205-
}
206-
ColumnInfo[] columnInfos = { new ColumnInfo("Type"), new ColumnInfo("Description"), new ColumnInfo("Project"), new ColumnInfo("Component"), new ColumnInfo("Line", hAlignment.Right), new ColumnInfo("Column", hAlignment.Right) };
184+
return;
185+
}
207186

208-
var resultArray = _items.OfType<IExportable>().Select(result => result.ToArray()).ToArray();
187+
ColumnInfo[] columnInfos = { new ColumnInfo("Type"), new ColumnInfo("Description"), new ColumnInfo("Project"), new ColumnInfo("Component"), new ColumnInfo("Line", hAlignment.Right), new ColumnInfo("Column", hAlignment.Right) };
209188

210-
var resource = _items.Count == 1
211-
? ToDoExplorerUI.ToDoExplorer_NumberOfIssuesFound_Singular
212-
: ToDoExplorerUI.ToDoExplorer_NumberOfIssuesFound_Plural;
189+
var resultArray = _items.OfType<IExportable>().Select(result => result.ToArray()).ToArray();
213190

214-
var title = string.Format(resource, DateTime.Now.ToString(CultureInfo.InvariantCulture), _items.Count);
191+
var resource = _items.Count == 1
192+
? ToDoExplorerUI.ToDoExplorer_NumberOfIssuesFound_Singular
193+
: ToDoExplorerUI.ToDoExplorer_NumberOfIssuesFound_Plural;
215194

216-
var textResults = title + Environment.NewLine + string.Join("", _items.OfType<IExportable>().Select(result => result.ToClipboardString() + Environment.NewLine).ToArray());
217-
var csvResults = ExportFormatter.Csv(resultArray, title, columnInfos);
218-
var htmlResults = ExportFormatter.HtmlClipboardFragment(resultArray, title, columnInfos);
219-
var rtfResults = ExportFormatter.RTF(resultArray, title);
195+
var title = string.Format(resource, DateTime.Now.ToString(CultureInfo.InvariantCulture), _items.Count);
220196

221-
// todo: verify that this disposing this stream breaks the xmlSpreadsheetDataFormat
222-
var stream = ExportFormatter.XmlSpreadsheetNew(resultArray, title, columnInfos);
197+
var textResults = title + Environment.NewLine + string.Join("", _items.OfType<IExportable>().Select(result => result.ToClipboardString() + Environment.NewLine).ToArray());
198+
var csvResults = ExportFormatter.Csv(resultArray, title, columnInfos);
199+
var htmlResults = ExportFormatter.HtmlClipboardFragment(resultArray, title, columnInfos);
200+
var rtfResults = ExportFormatter.RTF(resultArray, title);
223201

224-
IClipboardWriter _clipboard = new ClipboardWriter();
225-
//Add the formats from richest formatting to least formatting
226-
_clipboard.AppendStream(DataFormats.GetDataFormat(xmlSpreadsheetDataFormat).Name, stream);
227-
_clipboard.AppendString(DataFormats.Rtf, rtfResults);
228-
_clipboard.AppendString(DataFormats.Html, htmlResults);
229-
_clipboard.AppendString(DataFormats.CommaSeparatedValue, csvResults);
230-
_clipboard.AppendString(DataFormats.UnicodeText, textResults);
202+
// todo: verify that this disposing this stream breaks the xmlSpreadsheetDataFormat
203+
var stream = ExportFormatter.XmlSpreadsheetNew(resultArray, title, columnInfos);
231204

232-
_clipboard.Flush();
205+
IClipboardWriter _clipboard = new ClipboardWriter();
206+
//Add the formats from richest formatting to least formatting
207+
_clipboard.AppendStream(DataFormats.GetDataFormat(xmlSpreadsheetDataFormat).Name, stream);
208+
_clipboard.AppendString(DataFormats.Rtf, rtfResults);
209+
_clipboard.AppendString(DataFormats.Html, htmlResults);
210+
_clipboard.AppendString(DataFormats.CommaSeparatedValue, csvResults);
211+
_clipboard.AppendString(DataFormats.UnicodeText, textResults);
233212

234-
});
235-
}
213+
_clipboard.Flush();
236214
}
237215

238-
private CommandBase _openTodoSettings;
239-
public CommandBase OpenTodoSettings
216+
public void ExecuteOpenTodoSettingsCommand(object obj)
240217
{
241-
get
218+
using (var window = _settingsFormFactory.Create(SettingsViews.TodoSettings))
242219
{
243-
if (_openTodoSettings != null)
244-
{
245-
return _openTodoSettings;
246-
}
247-
return _openTodoSettings = new DelegateCommand(LogManager.GetCurrentClassLogger(), _ =>
248-
{
249-
using (var window = _settingsFormFactory.Create(SettingsViews.TodoSettings))
250-
{
251-
window.ShowDialog();
252-
_settingsFormFactory.Release(window);
253-
}
254-
});
220+
window.ShowDialog();
221+
_settingsFormFactory.Release(window);
255222
}
256223
}
257224

258-
private readonly Lazy<NavigateCommand> _navigateCommand;
259-
public INavigateCommand NavigateCommand => _navigateCommand.Value;
260-
261225
private IEnumerable<ToDoItem> GetToDoMarkers(CommentNode comment)
262226
{
263227
var markers = _configService.LoadConfiguration().UserSettings.ToDoListSettings.ToDoMarkers;

0 commit comments

Comments
 (0)