[WPF] Simplified ListBox/ListView selection models
Really overthought this to begin with. The former solution should perform better, but it was proving difficult to debug for a negligible gain. A better design for XWTs access of selected items can just as easily fix any performance issues.
This commit is contained in:
Родитель
016e65b07b
Коммит
463f793ac7
|
@ -37,108 +37,11 @@ namespace Xwt.WPFBackend
|
|||
public class ExListBox
|
||||
: SWC.ListBox, IWpfWidget
|
||||
{
|
||||
public ExListBox()
|
||||
{
|
||||
SelectedIndexes = new ObservableCollection<int> ();
|
||||
}
|
||||
|
||||
public WidgetBackend Backend {
|
||||
get;
|
||||
set;
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedIndexesProperty = DependencyProperty.Register (
|
||||
"SelectedIndexes",
|
||||
typeof (ICollection<int>), typeof (ExListBox),
|
||||
new UIPropertyMetadata (OnSelectedIndexesPropertyChanged));
|
||||
|
||||
public ICollection<int> SelectedIndexes
|
||||
{
|
||||
get { return (ICollection<int>) GetValue (SelectedIndexesProperty); }
|
||||
set { SetValue (SelectedIndexesProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnSelectionChanged (SelectionChangedEventArgs e)
|
||||
{
|
||||
if (this.changingSelection) {
|
||||
base.OnSelectionChanged (e);
|
||||
return;
|
||||
}
|
||||
|
||||
this.changingSelection = true;
|
||||
if (e.AddedItems != null) {
|
||||
foreach (object item in e.AddedItems) {
|
||||
SelectedIndexes.Add (Items.IndexOf (item));
|
||||
}
|
||||
}
|
||||
|
||||
if (e.RemovedItems != null) {
|
||||
foreach (object item in e.RemovedItems) {
|
||||
SelectedIndexes.Remove (Items.IndexOf (item));
|
||||
}
|
||||
}
|
||||
|
||||
this.changingSelection = false;
|
||||
base.OnSelectionChanged (e);
|
||||
}
|
||||
|
||||
protected virtual void OnSelectedIndexesChanged (DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var oldNotifying = e.OldValue as INotifyCollectionChanged;
|
||||
if (oldNotifying != null)
|
||||
oldNotifying.CollectionChanged -= SelectedIndexesChanged;
|
||||
|
||||
var newNotifying = e.NewValue as INotifyCollectionChanged;
|
||||
if (newNotifying != null)
|
||||
newNotifying.CollectionChanged += SelectedIndexesChanged;
|
||||
}
|
||||
|
||||
private bool changingSelection;
|
||||
private void SelectedIndexesChanged (object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (this.changingSelection)
|
||||
return;
|
||||
|
||||
this.changingSelection = true;
|
||||
|
||||
if (SelectionMode == SWC.SelectionMode.Single) {
|
||||
SelectedItem = null;
|
||||
if (e.NewItems != null && e.NewItems.Count > 0)
|
||||
SelectedItem = Items [(int) e.NewItems [0]];
|
||||
|
||||
this.changingSelection = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Reset) {
|
||||
SelectedItems.Clear();
|
||||
foreach (int index in SelectedIndexes)
|
||||
{
|
||||
SelectedItems.Add (Items[index]);
|
||||
if (SelectionMode == SWC.SelectionMode.Single)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (e.NewItems != null) {
|
||||
foreach (int index in e.NewItems)
|
||||
SelectedItems.Add (Items[index]);
|
||||
}
|
||||
|
||||
if (e.OldItems != null) {
|
||||
foreach (int index in e.OldItems)
|
||||
SelectedItems.Remove (Items [index]);
|
||||
}
|
||||
}
|
||||
|
||||
this.changingSelection = false;
|
||||
}
|
||||
|
||||
private static void OnSelectedIndexesPropertyChanged (DependencyObject dobj, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var listbox = (ExListBox) dobj;
|
||||
listbox.OnSelectedIndexesChanged (e);
|
||||
}
|
||||
|
||||
protected override System.Windows.Size MeasureOverride (System.Windows.Size constraint)
|
||||
{
|
||||
var s = base.MeasureOverride (constraint);
|
||||
|
|
|
@ -24,13 +24,6 @@
|
|||
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||
// THE SOFTWARE.
|
||||
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using SWC = System.Windows.Controls;
|
||||
|
@ -40,11 +33,6 @@ namespace Xwt.WPFBackend
|
|||
public class ExListView
|
||||
: SWC.ListView, IWpfWidget
|
||||
{
|
||||
public ExListView()
|
||||
{
|
||||
SelectedIndexes = new ObservableCollection<int> ();
|
||||
}
|
||||
|
||||
public WidgetBackend Backend { get; set; }
|
||||
|
||||
protected override System.Windows.Size MeasureOverride (System.Windows.Size constraint)
|
||||
|
@ -58,102 +46,5 @@ namespace Xwt.WPFBackend
|
|||
s = Backend.MeasureOverride (constraint, s);
|
||||
return s;
|
||||
}
|
||||
|
||||
protected override System.Windows.Size ArrangeOverride (System.Windows.Size arrangeBounds)
|
||||
{
|
||||
return base.ArrangeOverride (arrangeBounds);
|
||||
}
|
||||
|
||||
public static readonly DependencyProperty SelectedIndexesProperty = DependencyProperty.Register (
|
||||
"SelectedIndexes",
|
||||
typeof (ICollection<int>), typeof (ExListView),
|
||||
new UIPropertyMetadata (OnSelectedIndexesPropertyChanged));
|
||||
|
||||
public ICollection<int> SelectedIndexes
|
||||
{
|
||||
get { return (ICollection<int>) GetValue (SelectedIndexesProperty); }
|
||||
set { SetValue (SelectedIndexesProperty, value); }
|
||||
}
|
||||
|
||||
protected override void OnSelectionChanged (SelectionChangedEventArgs e)
|
||||
{
|
||||
if (this.changingSelection) {
|
||||
base.OnSelectionChanged (e);
|
||||
return;
|
||||
}
|
||||
|
||||
this.changingSelection = true;
|
||||
if (e.AddedItems != null) {
|
||||
foreach (object item in e.AddedItems) {
|
||||
SelectedIndexes.Add (Items.IndexOf (item));
|
||||
}
|
||||
}
|
||||
|
||||
if (e.RemovedItems != null) {
|
||||
foreach (object item in e.RemovedItems) {
|
||||
SelectedIndexes.Remove (Items.IndexOf (item));
|
||||
}
|
||||
}
|
||||
|
||||
this.changingSelection = false;
|
||||
base.OnSelectionChanged (e);
|
||||
}
|
||||
|
||||
protected virtual void OnSelectedIndexesChanged (DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var oldNotifying = e.OldValue as INotifyCollectionChanged;
|
||||
if (oldNotifying != null)
|
||||
oldNotifying.CollectionChanged -= SelectedIndexesChanged;
|
||||
|
||||
var newNotifying = e.NewValue as INotifyCollectionChanged;
|
||||
if (newNotifying != null)
|
||||
newNotifying.CollectionChanged += SelectedIndexesChanged;
|
||||
}
|
||||
|
||||
private bool changingSelection;
|
||||
private void SelectedIndexesChanged (object sender, NotifyCollectionChangedEventArgs e)
|
||||
{
|
||||
if (this.changingSelection)
|
||||
return;
|
||||
|
||||
this.changingSelection = true;
|
||||
|
||||
if (SelectionMode == SWC.SelectionMode.Single) {
|
||||
SelectedItem = null;
|
||||
if (e.NewItems != null && e.NewItems.Count > 0)
|
||||
SelectedItem = Items [(int) e.NewItems [0]];
|
||||
|
||||
this.changingSelection = false;
|
||||
return;
|
||||
}
|
||||
|
||||
if (e.Action == NotifyCollectionChangedAction.Reset) {
|
||||
SelectedItems.Clear();
|
||||
foreach (int index in SelectedIndexes)
|
||||
{
|
||||
SelectedItems.Add (Items[index]);
|
||||
if (SelectionMode == SWC.SelectionMode.Single)
|
||||
break;
|
||||
}
|
||||
} else {
|
||||
if (e.NewItems != null) {
|
||||
foreach (int index in e.NewItems)
|
||||
SelectedItems.Add (Items[index]);
|
||||
}
|
||||
|
||||
if (e.OldItems != null) {
|
||||
foreach (int index in e.OldItems)
|
||||
SelectedItems.Remove (Items [index]);
|
||||
}
|
||||
}
|
||||
|
||||
this.changingSelection = false;
|
||||
}
|
||||
|
||||
private static void OnSelectedIndexesPropertyChanged (DependencyObject dobj, DependencyPropertyChangedEventArgs e)
|
||||
{
|
||||
var view = (ExListView) dobj;
|
||||
view.OnSelectedIndexesChanged (e);
|
||||
}
|
||||
}
|
||||
}
|
|
@ -91,19 +91,26 @@ namespace Xwt.WPFBackend
|
|||
ListBox.UnselectAll();
|
||||
}
|
||||
|
||||
public int[] SelectedRows
|
||||
{
|
||||
get { return ListBox.SelectedIndexes.ToArray (); }
|
||||
public int[] SelectedRows {
|
||||
get { return ListBox.SelectedItems.Cast<object>().Select (ListBox.Items.IndexOf).ToArray(); }
|
||||
}
|
||||
|
||||
public void SelectRow (int pos)
|
||||
{
|
||||
ListBox.SelectedIndexes.Add (pos);
|
||||
object item = ListBox.Items [pos];
|
||||
if (ListBox.SelectionMode == System.Windows.Controls.SelectionMode.Single)
|
||||
ListBox.SelectedItem = item;
|
||||
else
|
||||
ListBox.SelectedItems.Add (item);
|
||||
}
|
||||
|
||||
public void UnselectRow (int pos)
|
||||
{
|
||||
ListBox.SelectedIndexes.Remove (pos);
|
||||
object item = ListBox.Items [pos];
|
||||
if (ListBox.SelectionMode == System.Windows.Controls.SelectionMode.Extended)
|
||||
ListBox.SelectedItems.Remove (item);
|
||||
else if (ListBox.SelectedItem == item)
|
||||
ListBox.SelectedItem = null;
|
||||
}
|
||||
|
||||
public override void EnableEvent (object eventId)
|
||||
|
|
|
@ -85,7 +85,7 @@ namespace Xwt.WPFBackend
|
|||
}
|
||||
|
||||
public int[] SelectedRows {
|
||||
get { return ListView.SelectedIndexes.ToArray (); }
|
||||
get { return ListView.SelectedItems.Cast<object>().Select (ListView.Items.IndexOf).ToArray (); }
|
||||
}
|
||||
|
||||
public object AddColumn (ListViewColumn col)
|
||||
|
@ -151,12 +151,20 @@ namespace Xwt.WPFBackend
|
|||
|
||||
public void SelectRow (int pos)
|
||||
{
|
||||
ListView.SelectedIndexes.Add (pos);
|
||||
object item = ListView.Items [pos];
|
||||
if (ListView.SelectionMode == System.Windows.Controls.SelectionMode.Single)
|
||||
ListView.SelectedItem = item;
|
||||
else
|
||||
ListView.SelectedItems.Add (item);
|
||||
}
|
||||
|
||||
public void UnselectRow (int pos)
|
||||
{
|
||||
ListView.SelectedIndexes.Remove (pos);
|
||||
object item = ListView.Items [pos];
|
||||
if (ListView.SelectionMode == System.Windows.Controls.SelectionMode.Extended)
|
||||
ListView.SelectedItems.Remove (item);
|
||||
else if (ListView.SelectedItem == item)
|
||||
ListView.SelectedItem = null;
|
||||
}
|
||||
|
||||
public override void EnableEvent(object eventId)
|
||||
|
|
Загрузка…
Ссылка в новой задаче