Replace ResultItem usercontrol with listbox to improve ui performance

This commit is contained in:
qianlifeng
2014-02-19 22:50:15 +08:00
parent 729640d6ec
commit 4736921d05
5 changed files with 142 additions and 160 deletions

View File

@@ -1,9 +1,9 @@
using System.Collections.Generic;
using System.Linq;
using System.Windows;
using System.Diagnostics;
using System.Windows.Controls;
using Wox.Helper;
using Wox.Plugin;
using Point = System.Windows.Point;
namespace Wox
{
@@ -11,70 +11,37 @@ namespace Wox
{
public bool Dirty { get; set; }
public delegate void ResultItemsChanged();
public event ResultItemsChanged resultItemChangedEvent;
protected virtual void OnResultItemChangedEvent()
{
ResultItemsChanged handler = resultItemChangedEvent;
if (handler != null) handler();
}
public void AddResults(List<Result> results)
{
if (results.Count == 0) return;
if (Dirty)
{
Dirty = false;
pnlContainer.Children.Clear();
lbResults.Items.Clear();
}
for (int i = 0; i < results.Count; i++)
foreach (var result in results)
{
Result result = results[i];
if (!CheckExisted(result))
{
ResultItem control = new ResultItem(result);
pnlContainer.Children.Insert(GetInsertLocation(result.Score), control);
}
int position = GetInsertLocation(result.Score);
lbResults.Items.Insert(position, result);
}
lbResults.UpdateLayout();
SelectFirst();
pnlContainer.UpdateLayout();
double resultItemHeight = 0;
if (pnlContainer.Children.Count > 0)
{
var resultItem = pnlContainer.Children[0] as ResultItem;
if (resultItem != null)
resultItemHeight = resultItem.ActualHeight;
}
pnlContainer.Height = pnlContainer.Children.Count * resultItemHeight;
OnResultItemChangedEvent();
}
private bool CheckExisted(Result result)
{
return pnlContainer.Children.Cast<ResultItem>().Any(child => child.Result.Equals(result));
}
private int GetInsertLocation(int currentScore)
{
int location = pnlContainer.Children.Count;
if (pnlContainer.Children.Count == 0) return 0;
if (currentScore > ((ResultItem)pnlContainer.Children[0]).Result.Score) return 0;
int location = lbResults.Items.Count;
if (lbResults.Items.Count == 0) return 0;
if (currentScore > ((Result)lbResults.Items[0]).Score) return 0;
for (int index = 1; index < pnlContainer.Children.Count; index++)
for (int index = 1; index < lbResults.Items.Count; index++)
{
ResultItem next = pnlContainer.Children[index] as ResultItem;
ResultItem prev = pnlContainer.Children[index - 1] as ResultItem;
Result next = lbResults.Items[index] as Result;
Result prev = lbResults.Items[index - 1] as Result;
if (next != null && prev != null)
{
if ((currentScore >= next.Result.Score && currentScore <= prev.Result.Score))
if ((currentScore >= next.Score && currentScore <= prev.Score))
{
if (currentScore == next.Result.Score)
if (currentScore == next.Score)
{
location = index + 1;
}
@@ -89,40 +56,10 @@ namespace Wox
return location;
}
public int GetCurrentResultCount()
{
return pnlContainer.Children.Count;
}
public int GetCurrentSelectedResultIndex()
{
for (int i = 0; i < pnlContainer.Children.Count; i++)
{
var resultItemControl = pnlContainer.Children[i] as ResultItem;
if (resultItemControl != null && resultItemControl.Selected)
{
return i;
}
}
return -1;
}
public void UnSelectAll()
{
for (int i = 0; i < pnlContainer.Children.Count; i++)
{
var resultItemControl = pnlContainer.Children[i] as ResultItem;
if (resultItemControl != null && resultItemControl.Selected)
{
resultItemControl.Selected = false;
}
}
}
public void SelectNext()
{
int index = GetCurrentSelectedResultIndex();
if (index == pnlContainer.Children.Count - 1)
int index = lbResults.SelectedIndex;
if (index == lbResults.Items.Count - 1)
{
index = -1;
}
@@ -131,95 +68,44 @@ namespace Wox
public void SelectPrev()
{
int index = GetCurrentSelectedResultIndex();
int index = lbResults.SelectedIndex;
if (index == 0)
{
index = pnlContainer.Children.Count;
index = lbResults.Items.Count;
}
Select(index - 1);
}
private void Select(int index)
{
if (pnlContainer.Children.Count > 0)
{
int oldIndex = GetCurrentSelectedResultIndex();
UnSelectAll();
var resultItemControl = pnlContainer.Children[index] as ResultItem;
if (resultItemControl != null)
{
resultItemControl.Selected = true;
double scrollPosition = 0;
Point newItemBottomPoint = resultItemControl.TranslatePoint(new Point(0, resultItemControl.ActualHeight), pnlContainer);
scrollPosition = newItemBottomPoint.Y;
if (index == 0)
{
sv.ScrollToTop();
return;
}
if (index == pnlContainer.Children.Count - 1)
{
sv.ScrollToBottom();
return;
}
if (index < oldIndex)
{
//move up and old item is at the top of the scroll view
var scrollPostionY = sv.VerticalOffset - sv.VerticalOffset%resultItemControl.ActualHeight +
resultItemControl.ActualHeight;
if (newItemBottomPoint.Y - scrollPostionY == 0)
{
scrollPosition = sv.VerticalOffset - resultItemControl.ActualHeight;
}
else
{
return;
}
}
else
{
//move down and old item is at the bottom of scroll view
double scrollPostionY = (sv.ActualHeight + sv.VerticalOffset) - (sv.ActualHeight + sv.VerticalOffset)%resultItemControl.ActualHeight;
if (scrollPostionY == newItemBottomPoint.Y - resultItemControl.ActualHeight)
{
scrollPosition = newItemBottomPoint.Y - sv.ActualHeight;
}
else
{
return;
}
}
sv.ScrollToVerticalOffset(scrollPosition);
}
}
}
public void SelectFirst()
private void SelectFirst()
{
Select(0);
}
private void Select(int index)
{
if (index >= 0 && index < lbResults.Items.Count)
{
lbResults.SelectedItem = lbResults.Items.GetItemAt(index);
}
}
public Result AcceptSelect()
{
int index = GetCurrentSelectedResultIndex();
int index = lbResults.SelectedIndex;
if (index < 0) return null;
var resultItemControl = pnlContainer.Children[index] as ResultItem;
if (resultItemControl != null)
var result = lbResults.Items[index] as Result;
if (result != null)
{
if (resultItemControl.Result.Action != null)
if (result.Action != null)
{
resultItemControl.Result.Action(new ActionContext()
result.Action(new ActionContext()
{
SpecialKeyState = new KeyboardListener().CheckModifiers()
});
}
return resultItemControl.Result;
return result;
}
return null;
@@ -232,9 +118,15 @@ namespace Wox
public void Clear()
{
pnlContainer.Children.Clear();
pnlContainer.Height = 0;
OnResultItemChangedEvent();
lbResults.Items.Clear();
}
private void lbResults_SelectionChanged(object sender, SelectionChangedEventArgs e)
{
if (e.AddedItems.Count > 0)
{
lbResults.ScrollIntoView(e.AddedItems[0]);
}
}
}
}