From c270a5ff71761756fbdc14490c31fd3a293285cb Mon Sep 17 00:00:00 2001 From: ermau Date: Tue, 3 Apr 2012 10:29:23 -0400 Subject: [PATCH] [WPF] ListBoxBackend --- Xwt.WPF/Xwt.WPF.csproj | 2 + Xwt.WPF/Xwt.WPFBackend.Utilities/CellUtil.cs | 8 +- Xwt.WPF/Xwt.WPFBackend/DataConverter.cs | 4 +- Xwt.WPF/Xwt.WPFBackend/ExListBox.cs | 152 +++++++++++++++++++ Xwt.WPF/Xwt.WPFBackend/ListBoxBackend.cs | 111 ++++++++++++++ Xwt.WPF/Xwt.WPFBackend/ListViewBackend.cs | 4 +- 6 files changed, 273 insertions(+), 8 deletions(-) create mode 100644 Xwt.WPF/Xwt.WPFBackend/ExListBox.cs create mode 100644 Xwt.WPF/Xwt.WPFBackend/ListBoxBackend.cs diff --git a/Xwt.WPF/Xwt.WPF.csproj b/Xwt.WPF/Xwt.WPF.csproj index 8ac68bc2f..e6e49e818 100644 --- a/Xwt.WPF/Xwt.WPF.csproj +++ b/Xwt.WPF/Xwt.WPF.csproj @@ -70,6 +70,7 @@ + @@ -85,6 +86,7 @@ + diff --git a/Xwt.WPF/Xwt.WPFBackend.Utilities/CellUtil.cs b/Xwt.WPF/Xwt.WPFBackend.Utilities/CellUtil.cs index e903dfa43..4419e8ca1 100644 --- a/Xwt.WPF/Xwt.WPFBackend.Utilities/CellUtil.cs +++ b/Xwt.WPF/Xwt.WPFBackend.Utilities/CellUtil.cs @@ -68,15 +68,15 @@ internal static FrameworkElement CreateCellRenderer (TreeNode node, CellView vie throw new NotImplementedException (); } - internal static FrameworkElementFactory CreateBoundColumnTemplate (ListViewColumn column) + internal static FrameworkElementFactory CreateBoundColumnTemplate (CellViewCollection views) { - if (column.Views.Count == 1) - return CreateBoundCellRenderer (column.Views [0]); + if (views.Count == 1) + return CreateBoundCellRenderer (views [0]); FrameworkElementFactory container = new FrameworkElementFactory (typeof (StackPanel)); container.SetValue (StackPanel.OrientationProperty, Orientation.Horizontal); - foreach (CellView view in column.Views) { + foreach (CellView view in views) { container.AppendChild (CreateBoundCellRenderer (view)); } diff --git a/Xwt.WPF/Xwt.WPFBackend/DataConverter.cs b/Xwt.WPF/Xwt.WPFBackend/DataConverter.cs index 717b20688..0fe68921b 100644 --- a/Xwt.WPF/Xwt.WPFBackend/DataConverter.cs +++ b/Xwt.WPF/Xwt.WPFBackend/DataConverter.cs @@ -400,7 +400,7 @@ public static TransferDataType ToXwtDragType (this string type) // Scrollbar visibility - public static SWC.ScrollBarVisibility ToWpfScrollBarVisibility (ScrollPolicy policy) + public static SWC.ScrollBarVisibility ToWpfScrollBarVisibility (this ScrollPolicy policy) { switch (policy) { case ScrollPolicy.Always: @@ -415,7 +415,7 @@ public static SWC.ScrollBarVisibility ToWpfScrollBarVisibility (ScrollPolicy pol } } - public static ScrollPolicy ToXwtScrollPolicy (SWC.ScrollBarVisibility visibility) + public static ScrollPolicy ToXwtScrollPolicy (this SWC.ScrollBarVisibility visibility) { switch (visibility) { case SWC.ScrollBarVisibility.Auto: diff --git a/Xwt.WPF/Xwt.WPFBackend/ExListBox.cs b/Xwt.WPF/Xwt.WPFBackend/ExListBox.cs new file mode 100644 index 000000000..24092e457 --- /dev/null +++ b/Xwt.WPF/Xwt.WPFBackend/ExListBox.cs @@ -0,0 +1,152 @@ +// +// ExListBox.cs +// +// Author: +// Eric Maupin +// +// Copyright (c) 2012 Xamarin, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// 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.Specialized; +using System.Windows; +using System.Windows.Controls; +using SWC = System.Windows.Controls; + +namespace Xwt.WPFBackend +{ + public class ExListBox + : SWC.ListBox, IWpfWidget + { + public WidgetBackend Backend { + get; + set; + } + + public static readonly DependencyProperty SelectedIndexesProperty = DependencyProperty.Register ( + "SelectedIndexes", + typeof (ICollection), typeof (ExListView), + new UIPropertyMetadata (OnSelectedIndexesPropertyChanged)); + + public ICollection SelectedIndexes + { + get + { + if (SelectionMode == SWC.SelectionMode.Single) + throw new InvalidOperationException(); + + return (ICollection) 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; + + if (SelectionMode == SWC.SelectionMode.Single) + throw new InvalidOperationException(); + + 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); + return Backend.MeasureOverride (constraint, s); + } + } +} \ No newline at end of file diff --git a/Xwt.WPF/Xwt.WPFBackend/ListBoxBackend.cs b/Xwt.WPF/Xwt.WPFBackend/ListBoxBackend.cs new file mode 100644 index 000000000..0fa177f04 --- /dev/null +++ b/Xwt.WPF/Xwt.WPFBackend/ListBoxBackend.cs @@ -0,0 +1,111 @@ +// +// ListBoxBackend.cs +// +// Author: +// Eric Maupin +// +// Copyright (c) 2012 Xamarin, Inc. +// +// Permission is hereby granted, free of charge, to any person obtaining a copy +// of this software and associated documentation files (the "Software"), to deal +// in the Software without restriction, including without limitation the rights +// to use, copy, modify, merge, publish, distribute, sublicense, and/or sell +// copies of the Software, and to permit persons to whom the Software is +// furnished to do so, subject to the following conditions: +// +// The above copyright notice and this permission notice shall be included in +// all copies or substantial portions of the Software. +// +// THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR +// IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, +// FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE +// AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER +// LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, +// OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN +// THE SOFTWARE. + +using System.Linq; +using System.Windows; +using System.Windows.Controls; +using Xwt.Backends; +using Xwt.WPFBackend.Utilities; + +namespace Xwt.WPFBackend +{ + public class ListBoxBackend + : WidgetBackend, IListBoxBackend + { + public ListBoxBackend() + { + ListBox = new ExListBox(); + } + + public ScrollPolicy VerticalScrollPolicy + { + get { return ScrollViewer.GetVerticalScrollBarVisibility (ListBox).ToXwtScrollPolicy(); } + set { ScrollViewer.SetVerticalScrollBarVisibility (ListBox, value.ToWpfScrollBarVisibility ()); } + } + + public ScrollPolicy HorizontalScrollPolicy + { + get { return ScrollViewer.GetHorizontalScrollBarVisibility (ListBox).ToXwtScrollPolicy (); } + set { ScrollViewer.SetVerticalScrollBarVisibility (ListBox, value.ToWpfScrollBarVisibility ()); } + } + + public void SetViews (CellViewCollection views) + { + ListBox.ItemTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundColumnTemplate (views) }; + } + + public void SetSource (IListDataSource source, IBackend sourceBackend) + { + var dataSource = sourceBackend as ListDataSource; + if (dataSource != null) + ListBox.ItemsSource = dataSource; + else + ListBox.ItemsSource = new ListSourceNotifyWrapper (source); + } + + public void SetSelectionMode (SelectionMode mode) + { + switch (mode) { + case SelectionMode.Single: + ListBox.SelectionMode = System.Windows.Controls.SelectionMode.Single; + break; + case SelectionMode.Multiple: + ListBox.SelectionMode = System.Windows.Controls.SelectionMode.Extended; + break; + } + } + + public void SelectAll () + { + ListBox.SelectAll(); + } + + public void UnselectAll () + { + ListBox.UnselectAll(); + } + + public int[] SelectedRows + { + get { return ListBox.SelectedIndexes.ToArray (); } + } + + public void SelectRow (int pos) + { + ListBox.SelectedIndexes.Add (pos); + } + + public void UnselectRow (int pos) + { + ListBox.SelectedIndexes.Remove (pos); + } + + protected ExListBox ListBox { + get { return (ExListBox) Widget; } + set { Widget = value; } + } + } +} \ No newline at end of file diff --git a/Xwt.WPF/Xwt.WPFBackend/ListViewBackend.cs b/Xwt.WPF/Xwt.WPFBackend/ListViewBackend.cs index 48413ded6..93e699a66 100644 --- a/Xwt.WPF/Xwt.WPFBackend/ListViewBackend.cs +++ b/Xwt.WPF/Xwt.WPFBackend/ListViewBackend.cs @@ -91,7 +91,7 @@ public Xwt.ScrollPolicy HorizontalScrollPolicy public object AddColumn (ListViewColumn col) { var column = new GridViewColumn (); - column.CellTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundColumnTemplate (col) }; + column.CellTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundColumnTemplate (col.Views) }; if (col.HeaderView != null) column.HeaderTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundCellRenderer (col.HeaderView) }; else @@ -110,7 +110,7 @@ public void RemoveColumn (ListViewColumn col, object handle) public void UpdateColumn (ListViewColumn col, object handle, ListViewColumnChange change) { var column = (GridViewColumn) handle; - column.CellTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundColumnTemplate (col) }; + column.CellTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundColumnTemplate (col.Views) }; if (col.HeaderView != null) column.HeaderTemplate = new DataTemplate { VisualTree = CellUtil.CreateBoundCellRenderer (col.HeaderView) }; else