Move ResultListBox Visibility

1. Move ResultListBox Visibility from MainViewModel to ResultsViewModel
2. Refactoring
This commit is contained in:
bao-qian
2016-06-23 00:26:57 +01:00
parent 5102770ad5
commit b589a1a13e
8 changed files with 101 additions and 147 deletions

View File

@@ -1,12 +0,0 @@
using System.Windows;
namespace Wox.Helper
{
public static class VisibilityExtensions
{
public static bool IsVisible(this Visibility visibility)
{
return visibility == Visibility.Visible;
}
}
}

View File

@@ -53,6 +53,7 @@
<TextBox Style="{DynamicResource QueryBoxStyle}" <TextBox Style="{DynamicResource QueryBoxStyle}"
Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" Text="{Binding QueryText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
PreviewDragOver="OnPreviewDragOver" PreviewDragOver="OnPreviewDragOver"
TextChanged="OnTextChanged"
AllowDrop="True" AllowDrop="True"
Visibility="Visible" Visibility="Visible"
x:Name="QueryTextBox"> x:Name="QueryTextBox">
@@ -70,10 +71,10 @@
Style="{DynamicResource PendingLineStyle}" Visibility="{Binding ProgressBarVisibility, Mode=TwoWay}" Style="{DynamicResource PendingLineStyle}" Visibility="{Binding ProgressBarVisibility, Mode=TwoWay}"
Y1="0" Y2="0" X2="100" Height="2" Width="752" StrokeThickness="1"> Y1="0" Y2="0" X2="100" Height="2" Width="752" StrokeThickness="1">
</Line> </Line>
<ContentControl Visibility="{Binding ResultListBoxVisibility}" > <ContentControl>
<wox:ResultListBox DataContext="{Binding Results}" PreviewMouseDown="OnPreviewMouseButtonDown" /> <wox:ResultListBox DataContext="{Binding Results}" PreviewMouseDown="OnPreviewMouseButtonDown" />
</ContentControl> </ContentControl>
<ContentControl Visibility="{Binding ContextMenuVisibility}"> <ContentControl>
<wox:ResultListBox DataContext="{Binding ContextMenu}" PreviewMouseDown="OnPreviewMouseButtonDown" /> <wox:ResultListBox DataContext="{Binding ContextMenu}" PreviewMouseDown="OnPreviewMouseButtonDown" />
</ContentControl> </ContentControl>
</StackPanel> </StackPanel>

View File

@@ -57,7 +57,7 @@ namespace Wox
{ {
if (e.PropertyName == nameof(MainViewModel.MainWindowVisibility)) if (e.PropertyName == nameof(MainViewModel.MainWindowVisibility))
{ {
if (_viewModel.MainWindowVisibility.IsVisible()) if (Visibility == Visibility.Visible)
{ {
Activate(); Activate();
QueryTextBox.Focus(); QueryTextBox.Focus();
@@ -227,5 +227,10 @@ namespace Wox
e.Handled = true; e.Handled = true;
} }
} }
private void OnTextChanged(object sender, TextChangedEventArgs e)
{
QueryTextBox.CaretIndex = QueryTextBox.Text.Length;
}
} }
} }

View File

@@ -11,6 +11,7 @@
SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}" SelectedItem="{Binding SelectedItem, Mode=OneWayToSource}"
HorizontalContentAlignment="Stretch" ItemsSource="{Binding Results}" HorizontalContentAlignment="Stretch" ItemsSource="{Binding Results}"
Margin="{Binding Margin}" Margin="{Binding Margin}"
Visibility="{Binding Visbility}"
Style="{DynamicResource BaseListboxStyle}" Focusable="False" Style="{DynamicResource BaseListboxStyle}" Focusable="False"
KeyboardNavigation.DirectionalNavigation="Cycle" SelectionMode="Single" KeyboardNavigation.DirectionalNavigation="Cycle" SelectionMode="Single"
VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard" VirtualizingStackPanel.IsVirtualizing="True" VirtualizingStackPanel.VirtualizationMode="Standard"

View File

@@ -25,11 +25,8 @@ namespace Wox.ViewModel
{ {
#region Private Fields #region Private Fields
private Visibility _contextMenuVisibility;
private bool _queryHasReturn; private bool _queryHasReturn;
private Query _lastQuery; private Query _lastQuery;
private bool _ignoreTextChange;
private string _queryTextBeforeLoadContextMenu; private string _queryTextBeforeLoadContextMenu;
private string _queryText; private string _queryText;
@@ -65,8 +62,10 @@ namespace Wox.ViewModel
_userSelectedRecord = _userSelectedRecordStorage.Load(); _userSelectedRecord = _userSelectedRecordStorage.Load();
_topMostRecord = _topMostRecordStorage.Load(); _topMostRecord = _topMostRecordStorage.Load();
InitializeResultListBox(); ContextMenu = new ResultsViewModel(_settings);
InitializeContextMenu(); Results = new ResultsViewModel(_settings);
_selectedResults = Results;
InitializeKeyCommands(); InitializeKeyCommands();
RegisterResultsUpdatedEvent(); RegisterResultsUpdatedEvent();
@@ -78,7 +77,7 @@ namespace Wox.ViewModel
{ {
foreach (var pair in PluginManager.GetPluginsForInterface<IResultUpdated>()) foreach (var pair in PluginManager.GetPluginsForInterface<IResultUpdated>())
{ {
var plugin = (IResultUpdated) pair.Plugin; var plugin = (IResultUpdated)pair.Plugin;
plugin.ResultsUpdated += (s, e) => plugin.ResultsUpdated += (s, e) =>
{ {
Task.Run(() => Task.Run(() =>
@@ -96,9 +95,9 @@ namespace Wox.ViewModel
{ {
EscCommand = new RelayCommand(_ => EscCommand = new RelayCommand(_ =>
{ {
if (ContextMenuVisibility.IsVisible()) if (!ResultsSelected())
{ {
ContextMenuVisibility = Visibility.Collapsed; SelectedResults = Results;
} }
else else
{ {
@@ -108,26 +107,12 @@ namespace Wox.ViewModel
SelectNextItemCommand = new RelayCommand(_ => SelectNextItemCommand = new RelayCommand(_ =>
{ {
if (ContextMenuVisibility.IsVisible()) SelectedResults.SelectNextResult();
{
ContextMenu.SelectNextResult();
}
else
{
Results.SelectNextResult();
}
}); });
SelectPrevItemCommand = new RelayCommand(_ => SelectPrevItemCommand = new RelayCommand(_ =>
{ {
if (ContextMenuVisibility.IsVisible()) SelectedResults.SelectPrevResult();
{
ContextMenu.SelectPrevResult();
}
else
{
Results.SelectPrevResult();
}
}); });
@@ -147,12 +132,12 @@ namespace Wox.ViewModel
SelectNextPageCommand = new RelayCommand(_ => SelectNextPageCommand = new RelayCommand(_ =>
{ {
Results.SelectNextPage(); SelectedResults.SelectNextPage();
}); });
SelectPrevPageCommand = new RelayCommand(_ => SelectPrevPageCommand = new RelayCommand(_ =>
{ {
Results.SelectPrevPage(); SelectedResults.SelectPrevPage();
}); });
StartHelpCommand = new RelayCommand(_ => StartHelpCommand = new RelayCommand(_ =>
@@ -162,7 +147,7 @@ namespace Wox.ViewModel
OpenResultCommand = new RelayCommand(index => OpenResultCommand = new RelayCommand(index =>
{ {
var results = ContextMenuVisibility.IsVisible() ? ContextMenu : Results; var results = SelectedResults;
if (index != null) if (index != null)
{ {
@@ -182,7 +167,7 @@ namespace Wox.ViewModel
MainWindowVisibility = Visibility.Collapsed; MainWindowVisibility = Visibility.Collapsed;
} }
if (!ContextMenuVisibility.IsVisible()) if (ResultsSelected())
{ {
_userSelectedRecord.Add(result); _userSelectedRecord.Add(result);
_queryHistory.Add(result.OriginQuery.RawQuery); _queryHistory.Add(result.OriginQuery.RawQuery);
@@ -192,75 +177,18 @@ namespace Wox.ViewModel
LoadContextMenuCommand = new RelayCommand(_ => LoadContextMenuCommand = new RelayCommand(_ =>
{ {
if (!ContextMenuVisibility.IsVisible()) if (ResultsSelected())
{ {
var result = Results.SelectedItem?.Result; SelectedResults = ContextMenu;
if (result != null) // SelectedItem returns null if selection is empty.
{
var id = result.PluginID;
var menus = PluginManager.GetContextMenusForPlugin(result);
menus.Add(ContextMenuTopMost(result));
menus.Add(ContextMenuPluginInfo(id));
ContextMenu.Clear();
Task.Run(() =>
{
ContextMenu.AddResults(menus, id);
}, _updateToken);
ContextMenuVisibility = Visibility.Visible;
}
} }
else else
{ {
ContextMenuVisibility = Visibility.Collapsed; SelectedResults = Results;
} }
}); });
} }
private void InitializeResultListBox()
{
Results = new ResultsViewModel(_settings);
ResultListBoxVisibility = Visibility.Collapsed;
}
private void InitializeContextMenu()
{
ContextMenu = new ResultsViewModel(_settings);
ContextMenuVisibility = Visibility.Collapsed;
}
private void HandleQueryTextUpdated()
{
ProgressBarVisibility = Visibility.Hidden;
_updateSource?.Cancel();
_updateSource = new CancellationTokenSource();
_updateToken = _updateSource.Token;
if (ContextMenuVisibility.IsVisible())
{
QueryContextMenu();
}
else
{
string query = QueryText.Trim();
if (!string.IsNullOrEmpty(query))
{
Query(query);
//reset query history index after user start new query
ResetQueryHistoryIndex();
}
else
{
Results.Clear();
ResultListBoxVisibility = Visibility.Collapsed;
}
}
}
#endregion #endregion
#region ViewModel Properties #region ViewModel Properties
@@ -275,46 +203,52 @@ namespace Wox.ViewModel
set set
{ {
_queryText = value; _queryText = value;
if (_ignoreTextChange) ProgressBarVisibility = Visibility.Hidden;
_updateSource?.Cancel();
_updateSource = new CancellationTokenSource();
_updateToken = _updateSource.Token;
if (ResultsSelected())
{ {
_ignoreTextChange = false; QueryResults();
} }
else else
{ {
HandleQueryTextUpdated(); QueryContextMenu();
} }
} }
} }
public bool QueryTextSelected { get; set; } public bool QueryTextSelected { get; set; }
public Visibility ContextMenuVisibility private ResultsViewModel _selectedResults;
private ResultsViewModel SelectedResults
{ {
get { return _contextMenuVisibility; } get { return _selectedResults; }
set set
{ {
_contextMenuVisibility = value; _selectedResults = value;
if (ResultsSelected())
_ignoreTextChange = true;
if (!value.IsVisible())
{ {
QueryText = _queryTextBeforeLoadContextMenu; QueryText = _queryTextBeforeLoadContextMenu;
ResultListBoxVisibility = Visibility.Visible; ContextMenu.Visbility = Visibility.Collapsed;
} }
else else
{ {
_queryTextBeforeLoadContextMenu = QueryText; _queryTextBeforeLoadContextMenu = QueryText;
QueryText = ""; QueryText = "";
ResultListBoxVisibility = Visibility.Collapsed; Results.Visbility = Visibility.Collapsed;
} }
_selectedResults.Visbility = Visibility.Visible;
} }
} }
public Visibility ProgressBarVisibility { get; set; } public Visibility ProgressBarVisibility { get; set; }
public Visibility ResultListBoxVisibility { get; set; }
public Visibility MainWindowVisibility { get; set; } public Visibility MainWindowVisibility { get; set; }
public ICommand EscCommand { get; set; } public ICommand EscCommand { get; set; }
@@ -335,26 +269,48 @@ namespace Wox.ViewModel
private void QueryContextMenu() private void QueryContextMenu()
{ {
var contextMenuId = "Context Menu Id"; const string contextMenuId = "Context Menu Id";
var query = QueryText.ToLower(); var query = QueryText.ToLower().Trim();
if (!string.IsNullOrEmpty(query)) ContextMenu.Clear();
{
List<Result> filterResults = new List<Result>(); var selected = Results.SelectedItem?.Result;
foreach (var result in ContextMenu.Results.Select(r => r.Result))
if (selected != null) // SelectedItem returns null if selection is empty.
{
var id = selected.PluginID;
var results = PluginManager.GetContextMenusForPlugin(selected);
results.Add(ContextMenuTopMost(selected));
results.Add(ContextMenuPluginInfo(id));
if (!string.IsNullOrEmpty(query))
{ {
var matched = StringMatcher.IsMatch(result.Title, query) || var filtered = results.Where
StringMatcher.IsMatch(result.SubTitle, query); (
if (matched) r => StringMatcher.IsMatch(r.Title, query) ||
{ StringMatcher.IsMatch(r.SubTitle, query)
filterResults.Add(result); ).ToList();
} ContextMenu.AddResults(filtered, contextMenuId);
} }
ContextMenu.Clear(); else
Task.Run(() =>
{ {
ContextMenu.AddResults(filterResults, contextMenuId); ContextMenu.AddResults(results, contextMenuId);
}, _updateToken); }
}
}
private void QueryResults()
{
if (!string.IsNullOrEmpty(QueryText))
{
Query(QueryText.Trim());
//reset query history index after user start new query
ResetQueryHistoryIndex();
}
else
{
Results.Clear();
Results.Visbility = Visibility.Collapsed;
} }
} }
@@ -409,9 +365,6 @@ namespace Wox.ViewModel
} }
}); });
}, _updateToken); }, _updateToken);
} }
} }
@@ -463,7 +416,7 @@ namespace Wox.ViewModel
{ {
Title = InternationalizationManager.Instance.GetTranslation("cancelTopMostInThisQuery"), Title = InternationalizationManager.Instance.GetTranslation("cancelTopMostInThisQuery"),
IcoPath = "Images\\down.png", IcoPath = "Images\\down.png",
PluginDirectory = Infrastructure.Constant.ProgramDirectory, PluginDirectory = Constant.ProgramDirectory,
Action = _ => Action = _ =>
{ {
_topMostRecord.Remove(result); _topMostRecord.Remove(result);
@@ -478,7 +431,7 @@ namespace Wox.ViewModel
{ {
Title = InternationalizationManager.Instance.GetTranslation("setAsTopMostInThisQuery"), Title = InternationalizationManager.Instance.GetTranslation("setAsTopMostInThisQuery"),
IcoPath = "Images\\up.png", IcoPath = "Images\\up.png",
PluginDirectory = Infrastructure.Constant.ProgramDirectory, PluginDirectory = Constant.ProgramDirectory,
Action = _ => Action = _ =>
{ {
_topMostRecord.AddOrUpdate(result); _topMostRecord.AddOrUpdate(result);
@@ -514,16 +467,22 @@ namespace Wox.ViewModel
return menu; return menu;
} }
private bool ResultsSelected()
{
var selected = SelectedResults == Results;
return selected;
}
#endregion #endregion
#region Hotkey #region Hotkey
internal void SetHotkey(string hotkeyStr, EventHandler<HotkeyEventArgs> action) private void SetHotkey(string hotkeyStr, EventHandler<HotkeyEventArgs> action)
{ {
var hotkey = new HotkeyModel(hotkeyStr); var hotkey = new HotkeyModel(hotkeyStr);
SetHotkey(hotkey, action); SetHotkey(hotkey, action);
} }
public void SetHotkey(HotkeyModel hotkey, EventHandler<HotkeyEventArgs> action) private void SetHotkey(HotkeyModel hotkey, EventHandler<HotkeyEventArgs> action)
{ {
string hotkeyStr = hotkey.ToString(); string hotkeyStr = hotkey.ToString();
try try
@@ -584,7 +543,7 @@ namespace Wox.ViewModel
private void ToggleWox() private void ToggleWox()
{ {
if (!MainWindowVisibility.IsVisible()) if (MainWindowVisibility != Visibility.Visible)
{ {
MainWindowVisibility = Visibility.Visible; MainWindowVisibility = Visibility.Visible;
} }
@@ -629,7 +588,7 @@ namespace Wox.ViewModel
} }
else else
{ {
result.Score += _userSelectedRecord.GetSelectedCount(result)*5; result.Score += _userSelectedRecord.GetSelectedCount(result) * 5;
} }
} }
@@ -638,9 +597,9 @@ namespace Wox.ViewModel
Results.AddResults(list, metadata.ID); Results.AddResults(list, metadata.ID);
} }
if (list.Count > 0 && !ResultListBoxVisibility.IsVisible()) if (Results.Visbility != Visibility.Visible && list.Count > 0)
{ {
ResultListBoxVisibility = Visibility.Visible; Results.Visbility = Visibility.Visible;
} }
} }

View File

@@ -21,7 +21,7 @@ namespace Wox.ViewModel
public override bool Equals(object obj) public override bool Equals(object obj)
{ {
ResultViewModel r = obj as ResultViewModel; var r = obj as ResultViewModel;
if (r != null) if (r != null)
{ {
return Result.Equals(r.Result); return Result.Equals(r.Result);

View File

@@ -39,7 +39,7 @@ namespace Wox.ViewModel
#endregion #endregion
#region ViewModel Properties #region Properties
public int MaxHeight => MaxResults * 50; public int MaxHeight => MaxResults * 50;
@@ -47,6 +47,7 @@ namespace Wox.ViewModel
public ResultViewModel SelectedItem { get; set; } public ResultViewModel SelectedItem { get; set; }
public Thickness Margin { get; set; } public Thickness Margin { get; set; }
public Visibility Visbility { get; set; } = Visibility.Collapsed;
#endregion #endregion

View File

@@ -159,7 +159,6 @@
<Link>Properties\SolutionAssemblyInfo.cs</Link> <Link>Properties\SolutionAssemblyInfo.cs</Link>
</Compile> </Compile>
<Compile Include="CrashReporter.cs" /> <Compile Include="CrashReporter.cs" />
<Compile Include="Helper\VisibilityExtensions.cs" />
<Compile Include="Helper\SingletonWindowOpener.cs" /> <Compile Include="Helper\SingletonWindowOpener.cs" />
<Compile Include="PublicAPIInstance.cs" /> <Compile Include="PublicAPIInstance.cs" />
<Compile Include="ReportWindow.xaml.cs" /> <Compile Include="ReportWindow.xaml.cs" />