[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
|
public class ExListBox
|
||||||
: SWC.ListBox, IWpfWidget
|
: SWC.ListBox, IWpfWidget
|
||||||
{
|
{
|
||||||
public ExListBox()
|
|
||||||
{
|
|
||||||
SelectedIndexes = new ObservableCollection<int> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WidgetBackend Backend {
|
public WidgetBackend Backend {
|
||||||
get;
|
get;
|
||||||
set;
|
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)
|
protected override System.Windows.Size MeasureOverride (System.Windows.Size constraint)
|
||||||
{
|
{
|
||||||
var s = base.MeasureOverride (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
|
// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
|
||||||
// THE SOFTWARE.
|
// 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;
|
||||||
using System.Windows.Controls;
|
using System.Windows.Controls;
|
||||||
using SWC = System.Windows.Controls;
|
using SWC = System.Windows.Controls;
|
||||||
|
@ -40,11 +33,6 @@ namespace Xwt.WPFBackend
|
||||||
public class ExListView
|
public class ExListView
|
||||||
: SWC.ListView, IWpfWidget
|
: SWC.ListView, IWpfWidget
|
||||||
{
|
{
|
||||||
public ExListView()
|
|
||||||
{
|
|
||||||
SelectedIndexes = new ObservableCollection<int> ();
|
|
||||||
}
|
|
||||||
|
|
||||||
public WidgetBackend Backend { get; set; }
|
public WidgetBackend Backend { get; set; }
|
||||||
|
|
||||||
protected override System.Windows.Size MeasureOverride (System.Windows.Size constraint)
|
protected override System.Windows.Size MeasureOverride (System.Windows.Size constraint)
|
||||||
|
@ -58,102 +46,5 @@ namespace Xwt.WPFBackend
|
||||||
s = Backend.MeasureOverride (constraint, s);
|
s = Backend.MeasureOverride (constraint, s);
|
||||||
return 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();
|
ListBox.UnselectAll();
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] SelectedRows
|
public int[] SelectedRows {
|
||||||
{
|
get { return ListBox.SelectedItems.Cast<object>().Select (ListBox.Items.IndexOf).ToArray(); }
|
||||||
get { return ListBox.SelectedIndexes.ToArray (); }
|
|
||||||
}
|
}
|
||||||
|
|
||||||
public void SelectRow (int pos)
|
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)
|
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)
|
public override void EnableEvent (object eventId)
|
||||||
|
|
|
@ -85,7 +85,7 @@ namespace Xwt.WPFBackend
|
||||||
}
|
}
|
||||||
|
|
||||||
public int[] SelectedRows {
|
public int[] SelectedRows {
|
||||||
get { return ListView.SelectedIndexes.ToArray (); }
|
get { return ListView.SelectedItems.Cast<object>().Select (ListView.Items.IndexOf).ToArray (); }
|
||||||
}
|
}
|
||||||
|
|
||||||
public object AddColumn (ListViewColumn col)
|
public object AddColumn (ListViewColumn col)
|
||||||
|
@ -151,12 +151,20 @@ namespace Xwt.WPFBackend
|
||||||
|
|
||||||
public void SelectRow (int pos)
|
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)
|
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)
|
public override void EnableEvent(object eventId)
|
||||||
|
|
Загрузка…
Ссылка в новой задаче