Possible problem detected
This commit is contained in:
		| @@ -87,7 +87,7 @@ | |||||||
|             </ResourceDictionary> |             </ResourceDictionary> | ||||||
|         </Grid.Resources> |         </Grid.Resources> | ||||||
|     </Grid> |     </Grid> | ||||||
|     <ListView x:Name="DataList" Grid.Row="1" BackgroundColor="#222222" /> |     <!-- <ListView x:Name="DataList" Grid.Row="1" BackgroundColor="#222222" /> --> | ||||||
|     <ContentView |     <ContentView | ||||||
|          x:Name="_noDataView" |          x:Name="_noDataView" | ||||||
|          Grid.RowSpan="2" |          Grid.RowSpan="2" | ||||||
|   | |||||||
| @@ -2,230 +2,127 @@ | |||||||
| using System.Collections; | using System.Collections; | ||||||
| using System.Collections.Generic; | using System.Collections.Generic; | ||||||
| using System.Collections.Specialized; | using System.Collections.Specialized; | ||||||
| using System.Collections.ObjectModel; |  | ||||||
| using System.Linq; | using System.Linq; | ||||||
| using System.Reflection; | using System.Reflection; | ||||||
|  | using System.Runtime.CompilerServices; | ||||||
| using System.Windows.Input; | using System.Windows.Input; | ||||||
| using Xamarin.Forms; | using Xamarin.Forms; | ||||||
| using Aurora.Utils; | using Aurora.Utils; | ||||||
|  |  | ||||||
|  | [assembly: InternalsVisibleTo("Xamarin.Forms.DataGrid.UnitTest")] | ||||||
| namespace Aurora.Design.Components.DataGrid | namespace Aurora.Design.Components.DataGrid | ||||||
| { | { | ||||||
|     public partial class DataGrid : Grid |     public partial class DataGrid : Grid | ||||||
|     { |     { | ||||||
|         #region Private Fields |  | ||||||
|         private ObservableCollection<object> _internalItems; |  | ||||||
|  |  | ||||||
|         private Dictionary<int, SortingOrder> _sortingOrders; |  | ||||||
|  |  | ||||||
|         #endregion Fields |  | ||||||
|  |  | ||||||
|         #region Constructor |  | ||||||
|  |  | ||||||
|         public DataGrid() : this(ListViewCachingStrategy.RetainElement) |  | ||||||
|         { |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         public DataGrid(ListViewCachingStrategy cachingStrategy) |  | ||||||
|         { |  | ||||||
|             InitializeComponent(); |  | ||||||
|             BackgroundColor = Color.Transparent; |  | ||||||
|  |  | ||||||
|             _sortingOrders = new Dictionary<int, SortingOrder>(); |  | ||||||
|  |  | ||||||
|             DataList.ItemTemplate = new DataGridRowTemplateSelector(); |  | ||||||
|  |  | ||||||
|             DataList.ItemSelected += (s, e) => |  | ||||||
|             { |  | ||||||
|                 if (SelectionEnabled) |  | ||||||
|                 { |  | ||||||
|                     SelectedItem = DataList.SelectedItem; |  | ||||||
|                 } |  | ||||||
|                 else |  | ||||||
|                 { |  | ||||||
|                     DataList.SelectedItem = null; |  | ||||||
|                 } |  | ||||||
|  |  | ||||||
|                 ItemSelected?.Invoke(this, e); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             DataList.Refreshing += (s, e) => |  | ||||||
|             { |  | ||||||
|                 Refreshing?.Invoke(this, e); |  | ||||||
|             }; |  | ||||||
|  |  | ||||||
|             DataList.SetBinding(ListView.RowHeightProperty, new Binding("RowHeight", source: this)); |  | ||||||
|         } |  | ||||||
|         #endregion Constructor |  | ||||||
|  |  | ||||||
|         #region Public Fields |  | ||||||
|         public event EventHandler Refreshing; |         public event EventHandler Refreshing; | ||||||
|         public event EventHandler<SelectedItemChangedEventArgs> ItemSelected; |         public event EventHandler<SelectedItemChangedEventArgs> ItemSelected; | ||||||
|  |  | ||||||
|         #endregion Public Fields |  | ||||||
|  |  | ||||||
|         #region Bindable properties |         #region Bindable properties | ||||||
|         public static readonly BindableProperty ActiveRowColorProperty = |         public static readonly BindableProperty ActiveRowColorProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(ActiveRowColor), typeof(Color), typeof(DataGrid), Color.FromRgb(128, 144, 160), | ||||||
|                 nameof(ActiveRowColor), |                 coerceValue: (b, v) => | ||||||
|                 typeof(Color), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 Color.FromRgb(128, 144, 160), |  | ||||||
|                 coerceValue: (bindable, value) => |  | ||||||
|                 { |                 { | ||||||
|                     if (!(bindable as DataGrid).SelectionEnabled) |                     if (!(b as DataGrid).SelectionEnabled) | ||||||
|                         throw new InvalidOperationException("Datagrid must be SelectionEnabled=true to set ActiveRowColor"); |                         throw new InvalidOperationException("Datagrid must be SelectionEnabled=true to set ActiveRowColor"); | ||||||
|                     return value; |                     return v; | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty HeaderBackgroundProperty = |         public static readonly BindableProperty HeaderBackgroundProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(HeaderBackground), typeof(Color), typeof(DataGrid), Color.White, | ||||||
|                 nameof(HeaderBackground), |                 propertyChanged: (b, o, n) => | ||||||
|                 typeof(Color), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 Color.White, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (self._headerView != null && !self.HeaderBordersVisible) |                     if (self._headerView != null && !self.HeaderBordersVisible) | ||||||
|                         self._headerView.BackgroundColor = (Color)newValue; |                         self._headerView.BackgroundColor = (Color)n; | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty BorderColorProperty = |         public static readonly BindableProperty BorderColorProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(BorderColor), typeof(Color), typeof(DataGrid), Color.Black, | ||||||
|                 nameof(BorderColor), |                 propertyChanged: (b, o, n) => | ||||||
|                 typeof(Color), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 Color.Black, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (self.HeaderBordersVisible) |                     if (self.HeaderBordersVisible) | ||||||
|                         self._headerView.BackgroundColor = (Color)newValue; |                         self._headerView.BackgroundColor = (Color)n; | ||||||
|  |  | ||||||
|                     if (self.Columns != null && self.ItemsSource != null) |                     if (self.Columns != null && self.ItemsSource != null) | ||||||
|                         self.Reload(); |                         self.Reload(); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty RowsBackgroundColorPaletteProperty = |         public static readonly BindableProperty RowsBackgroundColorPaletteProperty = | ||||||
|             BindableProperty.Create(nameof(RowsBackgroundColorPalette), |             BindableProperty.Create(nameof(RowsBackgroundColorPalette), typeof(IColorProvider), typeof(DataGrid), new PaletteCollection { default(Color) }, | ||||||
|                 typeof(IColorProvider), |                 propertyChanged: (b, o, n) => | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 new PaletteCollection { default(Color) }, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (self.Columns != null && self.ItemsSource != null) |                     if (self.Columns != null && self.ItemsSource != null) | ||||||
|                         self.Reload(); |                         self.Reload(); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty RowsTextColorPaletteProperty = |         public static readonly BindableProperty RowsTextColorPaletteProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(RowsTextColorPalette), typeof(IColorProvider), typeof(DataGrid), new PaletteCollection { Color.Black }, | ||||||
|                 nameof(RowsTextColorPalette), |                 propertyChanged: (b, o, n) => | ||||||
|                 typeof(IColorProvider), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 new PaletteCollection { Color.Black }, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (self.Columns != null && self.ItemsSource != null) |                     if (self.Columns != null && self.ItemsSource != null) | ||||||
|                         self.Reload(); |                         self.Reload(); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty ColumnsProperty = |         public static readonly BindableProperty ColumnsProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(Columns), typeof(ColumnCollection), typeof(DataGrid), | ||||||
|                 nameof(Columns), |                 propertyChanged: (b, o, n) => (b as DataGrid).InitHeaderView(), | ||||||
|                 typeof(ColumnCollection), |                 defaultValueCreator: b => { return new ColumnCollection(); } | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |  | ||||||
|                     (bindable as DataGrid).InitHeaderView(); |  | ||||||
|                 }, |  | ||||||
|                 defaultValueCreator: bindable => { return new ColumnCollection(); } |  | ||||||
|             ); |             ); | ||||||
|  |  | ||||||
|         public static BindableProperty ItemsSourceProperty = |         public static readonly BindableProperty ItemsSourceProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(ItemsSource), typeof(IEnumerable), typeof(DataGrid), null, | ||||||
|                 propertyName: nameof(ItemsSource), |                 propertyChanged: (b, o, n) => | ||||||
|                 returnType: typeof(IEnumerable), |  | ||||||
|                 declaringType: typeof(DataGrid), |  | ||||||
|                 defaultBindingMode: BindingMode.TwoWay, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |                 { | ||||||
|                     DataGrid self = bindable as DataGrid; |                     DataGrid self = b as DataGrid; | ||||||
|                     //ObservableCollection Tracking  |                     //ObservableCollection Tracking  | ||||||
|                     if (oldValue != null && oldValue is INotifyCollectionChanged) |                     if (o != null && o is INotifyCollectionChanged) | ||||||
|                     { |                         (o as INotifyCollectionChanged).CollectionChanged -= self.HandleItemsSourceCollectionChanged; | ||||||
|                         (oldValue as INotifyCollectionChanged).CollectionChanged -= self.HandleItemsSourceCollectionChanged; |  | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     if (newValue != null && newValue is INotifyCollectionChanged) |                     if (n != null) | ||||||
|                     { |                     { | ||||||
|                         (newValue as INotifyCollectionChanged).CollectionChanged += self.HandleItemsSourceCollectionChanged; |                         if (n is INotifyCollectionChanged) | ||||||
|  |                             (n as INotifyCollectionChanged).CollectionChanged += self.HandleItemsSourceCollectionChanged; | ||||||
|  |  | ||||||
|                         self.InternalItems = new ObservableCollection<object>(((IEnumerable<object>)newValue)); |                         self.InternalItems = new List<object>(((IEnumerable)n).Cast<object>()); | ||||||
|                         //Assign listview item source |  | ||||||
|                         self.DataList.ItemsSource = self.InternalItems; |  | ||||||
|                         self.DataList.SetBinding(ListView.ItemsSourceProperty, new Binding("ItemsSource", source: self)); |  | ||||||
|                     } |                     } | ||||||
|  |  | ||||||
|                     if (self.SelectedItem != null && !self.InternalItems.Contains(self.SelectedItem)) |                     if (self.SelectedItem != null && !self.InternalItems.Contains(self.SelectedItem)) | ||||||
|                     { |  | ||||||
|                         self.SelectedItem = null; |                         self.SelectedItem = null; | ||||||
|                     } |  | ||||||
|  |  | ||||||
|                     if (self.NoDataView != null) |                     if (self.NoDataView != null) | ||||||
|                     { |                     { | ||||||
|                         if (self.ItemsSource == null || self.InternalItems.Count() == 0) |                         if (self.ItemsSource == null || self.InternalItems.Count() == 0) | ||||||
|                         { |  | ||||||
|                             self._noDataView.IsVisible = true; |                             self._noDataView.IsVisible = true; | ||||||
|                         } |  | ||||||
|  |  | ||||||
|                         else if (self._noDataView.IsVisible) |                         else if (self._noDataView.IsVisible) | ||||||
|                         { |  | ||||||
|                             self._noDataView.IsVisible = false; |                             self._noDataView.IsVisible = false; | ||||||
|                         } |  | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|         private void HandleItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) |  | ||||||
|  |         void HandleItemsSourceCollectionChanged(object sender, NotifyCollectionChangedEventArgs e) | ||||||
|         { |         { | ||||||
|  |             InternalItems = new List<object>(((IEnumerable)sender).Cast<object>()); | ||||||
|             if (e.NewItems != null) |  | ||||||
|             { |  | ||||||
|                 foreach (object item in e.NewItems) |  | ||||||
|                 { |  | ||||||
|                     InternalItems.Add(item); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             if (e.OldItems != null) |  | ||||||
|             { |  | ||||||
|                 foreach (object item in e.OldItems) |  | ||||||
|                 { |  | ||||||
|                     InternalItems.Remove(item); |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|             if (SelectedItem != null && !InternalItems.Contains(SelectedItem)) |             if (SelectedItem != null && !InternalItems.Contains(SelectedItem)) | ||||||
|             { |  | ||||||
|                 SelectedItem = null; |                 SelectedItem = null; | ||||||
|             } |  | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         public static readonly BindableProperty RowHeightProperty = |         public static readonly BindableProperty RowHeightProperty = | ||||||
|             BindableProperty.Create(nameof(RowHeight), typeof(int), typeof(DataGrid), 40, |             BindableProperty.Create(nameof(RowHeight), typeof(int), typeof(DataGrid), 40, | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     self.DataList.RowHeight = (int)newValue; |                     self._listView.RowHeight = (int)n; | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |  | ||||||
|         public static readonly BindableProperty HeaderHeightProperty = |         public static readonly BindableProperty HeaderHeightProperty = | ||||||
|             BindableProperty.Create(nameof(HeaderHeight), typeof(int), typeof(DataGrid), 40, |             BindableProperty.Create(nameof(HeaderHeight), typeof(int), typeof(DataGrid), 40, | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     self._headerView.HeightRequest = (int)newValue; |                     self._headerView.HeightRequest = (int)n; | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty IsSortableProperty = |         public static readonly BindableProperty IsSortableProperty = | ||||||
| @@ -235,115 +132,75 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|             BindableProperty.Create(nameof(FontSize), typeof(double), typeof(DataGrid), 13.0); |             BindableProperty.Create(nameof(FontSize), typeof(double), typeof(DataGrid), 13.0); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty FontFamilyProperty = |         public static readonly BindableProperty FontFamilyProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(FontFamily), typeof(string), typeof(DataGrid), Font.Default.FontFamily); | ||||||
|                 nameof(FontFamily), |  | ||||||
|                 typeof(string), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 Font.Default.FontFamily); |  | ||||||
|  |  | ||||||
|         public static readonly BindableProperty SelectedItemProperty = |         public static readonly BindableProperty SelectedItemProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(SelectedItem), typeof(object), typeof(DataGrid), null, BindingMode.TwoWay, | ||||||
|                 nameof(SelectedItem), |                 coerceValue: (b, v) => | ||||||
|                 typeof(object), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 null, |  | ||||||
|                 BindingMode.TwoWay, |  | ||||||
|                 coerceValue: (bindable, value) => |  | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (!self.SelectionEnabled && value != null) |                     if (!self.SelectionEnabled && v != null) | ||||||
|                     { |  | ||||||
|                         throw new InvalidOperationException("Datagrid must be SelectionEnabled=true to set SelectedItem"); |                         throw new InvalidOperationException("Datagrid must be SelectionEnabled=true to set SelectedItem"); | ||||||
|                     } |                     if (self.InternalItems != null && self.InternalItems.Contains(v)) | ||||||
|                     if (self.InternalItems != null && self.InternalItems.Contains(value)) |                         return v; | ||||||
|                     { |  | ||||||
|                         return value; |  | ||||||
|                     } |  | ||||||
|                     else |                     else | ||||||
|                     { |  | ||||||
|                         return null; |                         return null; | ||||||
|                     } |  | ||||||
|                 }, |                 }, | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (self.DataList.SelectedItem != newValue) |                     if (self._listView.SelectedItem != n) | ||||||
|                     { |                         self._listView.SelectedItem = n; | ||||||
|                         self.DataList.SelectedItem = newValue; |  | ||||||
|                     } |  | ||||||
|                 } |                 } | ||||||
|             ); |             ); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty SelectionEnabledProperty = |         public static readonly BindableProperty SelectionEnabledProperty = | ||||||
|             BindableProperty.Create(nameof(SelectionEnabled), typeof(bool), typeof(DataGrid), true, |             BindableProperty.Create(nameof(SelectionEnabled), typeof(bool), typeof(DataGrid), true, | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (!self.SelectionEnabled && self.SelectedItem != null) |                     if (!self.SelectionEnabled && self.SelectedItem != null) | ||||||
|                     { |  | ||||||
|                         self.SelectedItem = null; |                         self.SelectedItem = null; | ||||||
|                     } |  | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty PullToRefreshCommandProperty = |         public static readonly BindableProperty PullToRefreshCommandProperty = | ||||||
|             BindableProperty.Create(nameof(PullToRefreshCommand), typeof(ICommand), typeof(DataGrid), null, |             BindableProperty.Create(nameof(PullToRefreshCommand), typeof(ICommand), typeof(DataGrid), null, | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (newValue == null) |                     if (n == null) | ||||||
|                     { |                     { | ||||||
|                         self.DataList.IsPullToRefreshEnabled = false; |                         self._listView.IsPullToRefreshEnabled = false; | ||||||
|                         self.DataList.RefreshCommand = null; |                         self._listView.RefreshCommand = null; | ||||||
|                     } |                     } | ||||||
|                     else |                     else | ||||||
|                     { |                     { | ||||||
|                         self.DataList.IsPullToRefreshEnabled = true; |                         self._listView.IsPullToRefreshEnabled = true; | ||||||
|                         self.DataList.RefreshCommand = newValue as ICommand; |                         self._listView.RefreshCommand = n as ICommand; | ||||||
|                     } |                     } | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty IsRefreshingProperty = |         public static readonly BindableProperty IsRefreshingProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(IsRefreshing), typeof(bool), typeof(DataGrid), false, BindingMode.TwoWay, | ||||||
|                 nameof(IsRefreshing), |                 propertyChanged: (b, o, n) => (b as DataGrid)._listView.IsRefreshing = (bool)n); | ||||||
|                 typeof(bool), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 false, |  | ||||||
|                 BindingMode.TwoWay, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |  | ||||||
|                     (bindable as DataGrid).DataList.IsRefreshing = (bool)newValue; |  | ||||||
|                 }); |  | ||||||
|  |  | ||||||
|         public static readonly BindableProperty BorderThicknessProperty = |         public static readonly BindableProperty BorderThicknessProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(BorderThickness), typeof(Thickness), typeof(DataGrid), new Thickness(1), | ||||||
|                 nameof(BorderThickness), |                 propertyChanged: (b, o, n) => | ||||||
|                 typeof(Thickness), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 new Thickness(1), |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |  | ||||||
|                 { |                 { | ||||||
|                     (bindable as DataGrid)._headerView.ColumnSpacing = ((Thickness)newValue).HorizontalThickness / 2; |                     (b as DataGrid)._headerView.ColumnSpacing = ((Thickness)n).HorizontalThickness / 2; | ||||||
|                     (bindable as DataGrid)._headerView.Padding = ((Thickness)newValue).HorizontalThickness / 2; |                     (b as DataGrid)._headerView.Padding = ((Thickness)n).HorizontalThickness / 2; | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty HeaderBordersVisibleProperty = |         public static readonly BindableProperty HeaderBordersVisibleProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(HeaderBordersVisible), typeof(bool), typeof(DataGrid), true, | ||||||
|                 nameof(HeaderBordersVisible), |                 propertyChanged: (b, o, n) => (b as DataGrid)._headerView.BackgroundColor = (bool)n ? (b as DataGrid).BorderColor : (b as DataGrid).HeaderBackground); | ||||||
|                 typeof(bool), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 true, |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => (bindable as DataGrid)._headerView.BackgroundColor = (bool)newValue ? (bindable as DataGrid).BorderColor : (bindable as DataGrid).HeaderBackground); |  | ||||||
|  |  | ||||||
|         public static readonly BindableProperty SortedColumnIndexProperty = |         public static readonly BindableProperty SortedColumnIndexProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(SortedColumnIndex), typeof(SortData), typeof(DataGrid), null, BindingMode.TwoWay, | ||||||
|                 nameof(SortedColumnIndex), |                 validateValue: (b, v) => | ||||||
|                 typeof(SortData), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 null, |  | ||||||
|                 BindingMode.TwoWay, |  | ||||||
|                 validateValue: (bindable, v) => |  | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     var sData = (SortData)v; |                     var sData = (SortData)v; | ||||||
|  |  | ||||||
|                     return |                     return | ||||||
| @@ -352,11 +209,11 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|                         self.Columns.Count == 0 || //columns not setted yet |                         self.Columns.Count == 0 || //columns not setted yet | ||||||
|                         (sData.Index < self.Columns.Count && self.Columns.ElementAt(sData.Index).SortingEnabled); |                         (sData.Index < self.Columns.Count && self.Columns.ElementAt(sData.Index).SortingEnabled); | ||||||
|                 }, |                 }, | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if (oldValue != newValue) |                     if (o != n) | ||||||
|                         self.SortItems((SortData)newValue); |                         self.SortItems((SortData)n); | ||||||
|                 }); |                 }); | ||||||
|  |  | ||||||
|  |  | ||||||
| @@ -364,28 +221,18 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|             BindableProperty.Create(nameof(HeaderLabelStyle), typeof(Style), typeof(DataGrid)); |             BindableProperty.Create(nameof(HeaderLabelStyle), typeof(Style), typeof(DataGrid)); | ||||||
|  |  | ||||||
|         public static readonly BindableProperty AscendingIconProperty = |         public static readonly BindableProperty AscendingIconProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(AscendingIcon), typeof(ImageSource), typeof(DataGrid), ImageSource.FromResource("Xamarin.Forms.DataGrid.up.png", typeof(DataGrid).GetTypeInfo().Assembly)); | ||||||
|                 nameof(AscendingIcon), |  | ||||||
|                 typeof(ImageSource), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 ImageSource.FromResource("Xamarin.Forms.DataGrid.up.png", |  | ||||||
|                 typeof(DataGrid).GetTypeInfo().Assembly)); |  | ||||||
|  |  | ||||||
|         public static readonly BindableProperty DescendingIconProperty = |         public static readonly BindableProperty DescendingIconProperty = | ||||||
|             BindableProperty.Create( |             BindableProperty.Create(nameof(DescendingIcon), typeof(ImageSource), typeof(DataGrid), ImageSource.FromResource("Xamarin.Forms.DataGrid.down.png", typeof(DataGrid).GetTypeInfo().Assembly)); | ||||||
|                 nameof(DescendingIcon), |  | ||||||
|                 typeof(ImageSource), |  | ||||||
|                 typeof(DataGrid), |  | ||||||
|                 ImageSource.FromResource("Xamarin.Forms.DataGrid.down.png", |  | ||||||
|                 typeof(DataGrid).GetTypeInfo().Assembly)); |  | ||||||
|  |  | ||||||
|         public static readonly BindableProperty DescendingIconStyleProperty = |         public static readonly BindableProperty DescendingIconStyleProperty = | ||||||
|             BindableProperty.Create(nameof(DescendingIconStyle), typeof(Style), typeof(DataGrid), null, |             BindableProperty.Create(nameof(DescendingIconStyle), typeof(Style), typeof(DataGrid), null, | ||||||
|  |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     var style = (newValue as Style).Setters.FirstOrDefault(x => x.Property == Image.SourceProperty); |                     var style = (n as Style).Setters.FirstOrDefault(x => x.Property == Image.SourceProperty); | ||||||
|                     if (style != null) |                     if (style != null) | ||||||
|                     { |                     { | ||||||
|                         if (style.Value is string vs) |                         if (style.Value is string vs) | ||||||
| @@ -397,19 +244,19 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|  |  | ||||||
|         public static readonly BindableProperty AscendingIconStyleProperty = |         public static readonly BindableProperty AscendingIconStyleProperty = | ||||||
|             BindableProperty.Create(nameof(AscendingIconStyle), typeof(Style), typeof(DataGrid), null, |             BindableProperty.Create(nameof(AscendingIconStyle), typeof(Style), typeof(DataGrid), null, | ||||||
|                 coerceValue: (bindable, v) => |                 coerceValue: (b, v) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|  |  | ||||||
|                     return v; |                     return v; | ||||||
|                 }, |                 }, | ||||||
|  |  | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     var self = bindable as DataGrid; |                     var self = b as DataGrid; | ||||||
|                     if ((newValue as Style).Setters.Any(x => x.Property == Image.SourceProperty)) |                     if ((n as Style).Setters.Any(x => x.Property == Image.SourceProperty)) | ||||||
|                     { |                     { | ||||||
|                         var style = (newValue as Style).Setters.FirstOrDefault(x => x.Property == Image.SourceProperty); |                         var style = (n as Style).Setters.FirstOrDefault(x => x.Property == Image.SourceProperty); | ||||||
|                         if (style != null) |                         if (style != null) | ||||||
|                         { |                         { | ||||||
|                             if (style.Value is string vs) |                             if (style.Value is string vs) | ||||||
| @@ -422,10 +269,10 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|  |  | ||||||
|         public static readonly BindableProperty NoDataViewProperty = |         public static readonly BindableProperty NoDataViewProperty = | ||||||
|             BindableProperty.Create(nameof(NoDataView), typeof(View), typeof(DataGrid), |             BindableProperty.Create(nameof(NoDataView), typeof(View), typeof(DataGrid), | ||||||
|                 propertyChanged: (bindable, oldValue, newValue) => |                 propertyChanged: (b, o, n) => | ||||||
|                 { |                 { | ||||||
|                     if (oldValue != newValue) |                     if (o != n) | ||||||
|                         (bindable as DataGrid)._noDataView.Content = newValue as View; |                         (b as DataGrid)._noDataView.Content = n as View; | ||||||
|                 }); |                 }); | ||||||
|         #endregion |         #endregion | ||||||
|  |  | ||||||
| @@ -472,20 +319,19 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|             set { SetValue(ItemsSourceProperty, value); } |             set { SetValue(ItemsSourceProperty, value); } | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         internal ObservableCollection<object> InternalItems |         IList<object> _internalItems; | ||||||
|  |  | ||||||
|  |         internal IList<object> InternalItems | ||||||
|         { |         { | ||||||
|             get { return _internalItems; } |             get { return _internalItems; } | ||||||
|             set |             set | ||||||
|             { |             { | ||||||
|                 if (value != _internalItems) |                 _internalItems = value; | ||||||
|                 { |  | ||||||
|                     _internalItems = value; |                 if (IsSortable && SortedColumnIndex != null) | ||||||
|                     if (IsSortable && SortedColumnIndex != null) |                     SortItems(SortedColumnIndex); | ||||||
|                     { |                 else | ||||||
|                         SortItems(SortedColumnIndex); |                     _listView.ItemsSource = _internalItems; | ||||||
|                     } |  | ||||||
|                 } |  | ||||||
|                 DataList.ItemsSource = _internalItems; |  | ||||||
|             } |             } | ||||||
|         } |         } | ||||||
|  |  | ||||||
| @@ -610,6 +456,51 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|         } |         } | ||||||
|         #endregion |         #endregion | ||||||
|  |  | ||||||
|  |         #region Fields | ||||||
|  |         Dictionary<int, SortingOrder> _sortingOrders; | ||||||
|  |         ListView _listView; | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|  |         #region ctor | ||||||
|  |  | ||||||
|  |         public DataGrid() : this(ListViewCachingStrategy.RecycleElement) | ||||||
|  |         { | ||||||
|  |         } | ||||||
|  |  | ||||||
|  |         public DataGrid(ListViewCachingStrategy cachingStrategy) | ||||||
|  |         { | ||||||
|  |             InitializeComponent(); | ||||||
|  |  | ||||||
|  |             _sortingOrders = new Dictionary<int, SortingOrder>(); | ||||||
|  |  | ||||||
|  |             _listView = new ListView(cachingStrategy) | ||||||
|  |             { | ||||||
|  |                 BackgroundColor = Color.FromHex("#222222"), | ||||||
|  |                 ItemTemplate = new DataGridRowTemplateSelector(), | ||||||
|  |             }; | ||||||
|  |             BackgroundColor = Color.Transparent; | ||||||
|  |  | ||||||
|  |             _listView.ItemSelected += (s, e) => | ||||||
|  |             { | ||||||
|  |                 if (SelectionEnabled) | ||||||
|  |                     SelectedItem = _listView.SelectedItem; | ||||||
|  |                 else | ||||||
|  |                     _listView.SelectedItem = null; | ||||||
|  |  | ||||||
|  |                 ItemSelected?.Invoke(this, e); | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             _listView.Refreshing += (s, e) => | ||||||
|  |             { | ||||||
|  |                 Refreshing?.Invoke(this, e); | ||||||
|  |             }; | ||||||
|  |  | ||||||
|  |             _listView.SetBinding(ListView.RowHeightProperty, new Binding("RowHeight", source: this)); | ||||||
|  |             Grid.SetRow(_listView, 1); | ||||||
|  |             Children.Add(_listView); | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|         #region UI Methods |         #region UI Methods | ||||||
|         protected override void OnParentSet() |         protected override void OnParentSet() | ||||||
|         { |         { | ||||||
| @@ -623,64 +514,13 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|             SetColumnsBindingContext(); |             SetColumnsBindingContext(); | ||||||
|         } |         } | ||||||
|  |  | ||||||
|         #endregion |  | ||||||
|  |  | ||||||
|         #region Private Methods |  | ||||||
|  |  | ||||||
|         private void Reload() |         private void Reload() | ||||||
|         { |         { | ||||||
|             InternalItems = new ObservableCollection<object>(_internalItems); |             InternalItems = new List<object>(_internalItems); | ||||||
|         } |         } | ||||||
|         private void SortItems(SortData sData) |         #endregion | ||||||
|         { |  | ||||||
|             if (InternalItems == null || sData.Index >= Columns.Count || !Columns[sData.Index].SortingEnabled) |  | ||||||
|                 return; |  | ||||||
|  |  | ||||||
|             var items = InternalItems; |         #region Header Creation Methods | ||||||
|             var column = Columns[sData.Index]; |  | ||||||
|             SortingOrder order = sData.Order; |  | ||||||
|  |  | ||||||
|             if (!IsSortable) |  | ||||||
|                 throw new InvalidOperationException("This DataGrid is not sortable"); |  | ||||||
|             else if (column.PropertyName == null) |  | ||||||
|                 throw new InvalidOperationException("Please set the PropertyName property of Column"); |  | ||||||
|  |  | ||||||
|             //Sort |  | ||||||
|             // if (order == SortingOrder.Descendant) |  | ||||||
|             //     items = items.OrderByDescending(x => ReflectionUtils.GetValueByPath(x, column.PropertyName)).ToList(); |  | ||||||
|             // else |  | ||||||
|             //     items = items.OrderBy(x => ReflectionUtils.GetValueByPath(x, column.PropertyName)).ToList(); |  | ||||||
|  |  | ||||||
|             column.SortingIcon.Style = (order == SortingOrder.Descendant) ? |  | ||||||
|                 AscendingIconStyle ?? (Style)_headerView.Resources["DescendingIconStyle"] : |  | ||||||
|                 DescendingIconStyle ?? (Style)_headerView.Resources["AscendingIconStyle"]; |  | ||||||
|  |  | ||||||
|             //Support DescendingIcon property (if setted) |  | ||||||
|             if (!column.SortingIcon.Style.Setters.Any(x => x.Property == Image.SourceProperty)) |  | ||||||
|             { |  | ||||||
|                 if (order == SortingOrder.Descendant && DescendingIconProperty.DefaultValue != DescendingIcon) |  | ||||||
|                     column.SortingIcon.Source = DescendingIcon; |  | ||||||
|                 if (order == SortingOrder.Ascendant && AscendingIconProperty.DefaultValue != AscendingIcon) |  | ||||||
|                     column.SortingIcon.Source = AscendingIcon; |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             for (int i = 0; i < Columns.Count; i++) |  | ||||||
|             { |  | ||||||
|                 if (i != sData.Index) |  | ||||||
|                 { |  | ||||||
|                     if (Columns[i].SortingIcon.Style != null) |  | ||||||
|                         Columns[i].SortingIcon.Style = null; |  | ||||||
|                     if (Columns[i].SortingIcon.Source != null) |  | ||||||
|                         Columns[i].SortingIcon.Source = null; |  | ||||||
|                     _sortingOrders[i] = SortingOrder.None; |  | ||||||
|                 } |  | ||||||
|             } |  | ||||||
|  |  | ||||||
|             _internalItems = items; |  | ||||||
|  |  | ||||||
|             _sortingOrders[sData.Index] = order; |  | ||||||
|             SortedColumnIndex = sData; |  | ||||||
|         } |  | ||||||
|  |  | ||||||
|         private View GetHeaderViewForColumn(DataGridColumn column) |         private View GetHeaderViewForColumn(DataGridColumn column) | ||||||
|         { |         { | ||||||
| @@ -750,7 +590,61 @@ namespace Aurora.Design.Components.DataGrid | |||||||
|                 foreach (var c in Columns) |                 foreach (var c in Columns) | ||||||
|                     c.BindingContext = BindingContext; |                     c.BindingContext = BindingContext; | ||||||
|         } |         } | ||||||
|  |         #endregion | ||||||
|  |  | ||||||
|         #endregion Private Methods |         #region Sorting methods | ||||||
|  |         internal void SortItems(SortData sData) | ||||||
|  |         { | ||||||
|  |             if (InternalItems == null || sData.Index >= Columns.Count || !Columns[sData.Index].SortingEnabled) | ||||||
|  |                 return; | ||||||
|  |  | ||||||
|  |             var items = InternalItems; | ||||||
|  |             var column = Columns[sData.Index]; | ||||||
|  |             SortingOrder order = sData.Order; | ||||||
|  |  | ||||||
|  |             if (!IsSortable) | ||||||
|  |                 throw new InvalidOperationException("This DataGrid is not sortable"); | ||||||
|  |             else if (column.PropertyName == null) | ||||||
|  |                 throw new InvalidOperationException("Please set the PropertyName property of Column"); | ||||||
|  |  | ||||||
|  |             //Sort | ||||||
|  |             if (order == SortingOrder.Descendant) | ||||||
|  |                 items = items.OrderByDescending(x => ReflectionUtils.GetValueByPath(x, column.PropertyName)).ToList(); | ||||||
|  |             else | ||||||
|  |                 items = items.OrderBy(x => ReflectionUtils.GetValueByPath(x, column.PropertyName)).ToList(); | ||||||
|  |  | ||||||
|  |             column.SortingIcon.Style = (order == SortingOrder.Descendant) ? | ||||||
|  |                 AscendingIconStyle ?? (Style)_headerView.Resources["DescendingIconStyle"] : | ||||||
|  |                 DescendingIconStyle ?? (Style)_headerView.Resources["AscendingIconStyle"]; | ||||||
|  |  | ||||||
|  |             //Support DescendingIcon property (if setted) | ||||||
|  |             if (!column.SortingIcon.Style.Setters.Any(x => x.Property == Image.SourceProperty)) | ||||||
|  |             { | ||||||
|  |                 if (order == SortingOrder.Descendant && DescendingIconProperty.DefaultValue != DescendingIcon) | ||||||
|  |                     column.SortingIcon.Source = DescendingIcon; | ||||||
|  |                 if (order == SortingOrder.Ascendant && AscendingIconProperty.DefaultValue != AscendingIcon) | ||||||
|  |                     column.SortingIcon.Source = AscendingIcon; | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             for (int i = 0; i < Columns.Count; i++) | ||||||
|  |             { | ||||||
|  |                 if (i != sData.Index) | ||||||
|  |                 { | ||||||
|  |                     if (Columns[i].SortingIcon.Style != null) | ||||||
|  |                         Columns[i].SortingIcon.Style = null; | ||||||
|  |                     if (Columns[i].SortingIcon.Source != null) | ||||||
|  |                         Columns[i].SortingIcon.Source = null; | ||||||
|  |                     _sortingOrders[i] = SortingOrder.None; | ||||||
|  |                 } | ||||||
|  |             } | ||||||
|  |  | ||||||
|  |             _internalItems = items; | ||||||
|  |  | ||||||
|  |             _sortingOrders[sData.Index] = order; | ||||||
|  |             SortedColumnIndex = sData; | ||||||
|  |  | ||||||
|  |             _listView.ItemsSource = _internalItems; | ||||||
|  |         } | ||||||
|  |         #endregion | ||||||
|     } |     } | ||||||
| } | } | ||||||
| @@ -3,7 +3,6 @@ | |||||||
|      xmlns="http://xamarin.com/schemas/2014/forms" |      xmlns="http://xamarin.com/schemas/2014/forms" | ||||||
|      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" |      xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||||||
|      xmlns:ml="clr-namespace:Aurora.Design.Components.MemberList" |      xmlns:ml="clr-namespace:Aurora.Design.Components.MemberList" | ||||||
|      xmlns:dg="clr-namespace:Aurora.Design.Components.DataGrid" |  | ||||||
|      xmlns:library="clr-namespace:Aurora.Design.Components.Library" |      xmlns:library="clr-namespace:Aurora.Design.Components.Library" | ||||||
|      x:Class="Aurora.Design.Views.Party.PartyView"> |      x:Class="Aurora.Design.Views.Party.PartyView"> | ||||||
|     <ContentView.Content> |     <ContentView.Content> | ||||||
| @@ -12,7 +11,7 @@ | |||||||
|                 <RowDefinition |                 <RowDefinition | ||||||
|                      Height="*"/> |                      Height="*"/> | ||||||
|             </Grid.RowDefinitions> |             </Grid.RowDefinitions> | ||||||
|             <StackLayout |             <!-- <StackLayout | ||||||
|                  Grid.Row="0"> |                  Grid.Row="0"> | ||||||
|                 <Label |                 <Label | ||||||
|                      Text="Party Members"/> |                      Text="Party Members"/> | ||||||
| @@ -21,97 +20,13 @@ | |||||||
|                      Members="{Binding Members}"/> |                      Members="{Binding Members}"/> | ||||||
|                 <Label |                 <Label | ||||||
|                      Text="Queue"/> |                      Text="Queue"/> | ||||||
|                 <dg:DataGrid |                  | ||||||
|                      x:Name="LibraryDataGrid" |             </StackLayout> --> | ||||||
|                      SelectionEnabled="True" |             <library:Library | ||||||
|                      RowHeight="30" |                      Grid.Row="1" | ||||||
|                      BorderColor="#3a3a3a" |  | ||||||
|                      BorderThickness="0" |  | ||||||
|                      HeaderHeight="40" |  | ||||||
|                      HeaderBackground="#222222" |  | ||||||
|                      ItemsSource="{Binding Queue}"> |  | ||||||
|                     <dg:DataGrid.HeaderLabelStyle> |  | ||||||
|                         <Style |  | ||||||
|                              TargetType="Label"> |  | ||||||
|                             <Setter |  | ||||||
|                                  Property="HorizontalOptions" |  | ||||||
|                                  Value="Start"/> |  | ||||||
|                             <Setter |  | ||||||
|                                  Property="FontSize" |  | ||||||
|                                  Value="14"/> |  | ||||||
|                             <Setter |  | ||||||
|                                  Property="TextColor" |  | ||||||
|                                  Value="White"/> |  | ||||||
|                         </Style> |  | ||||||
|                     </dg:DataGrid.HeaderLabelStyle> |  | ||||||
|                     <dg:DataGrid.GestureRecognizers> |  | ||||||
|                         <TapGestureRecognizer |  | ||||||
|                              NumberOfTapsRequired="2"/> |  | ||||||
|                     </dg:DataGrid.GestureRecognizers> |  | ||||||
|                     <dg:DataGrid.Columns> |  | ||||||
|                         <dg:DataGridColumn |  | ||||||
|                              Title="" |  | ||||||
|                              PropertyName="Icon" |  | ||||||
|                              Width="15"> |  | ||||||
|                             <dg:DataGridColumn.CellTemplate> |  | ||||||
|                                 <DataTemplate> |  | ||||||
|                                     <Image |  | ||||||
|                                          Source="../../Resources/unselected.png"/> |  | ||||||
|                                 </DataTemplate> |  | ||||||
|                             </dg:DataGridColumn.CellTemplate> |  | ||||||
|                         </dg:DataGridColumn> |  | ||||||
|                         <dg:DataGridColumn |  | ||||||
|                              Title="Title" |  | ||||||
|                              PropertyName="Metadata.Title" |  | ||||||
|                              Width="2*"> |  | ||||||
|                             <dg:DataGridColumn.CellTemplate> |  | ||||||
|                                 <DataTemplate> |  | ||||||
|                                     <Label |  | ||||||
|                                          LineBreakMode="TailTruncation" |  | ||||||
|                                          Text="{Binding .}"/> |  | ||||||
|                                 </DataTemplate> |  | ||||||
|                             </dg:DataGridColumn.CellTemplate> |  | ||||||
|                         </dg:DataGridColumn> |  | ||||||
|                         <dg:DataGridColumn |  | ||||||
|                              Title="Album" |  | ||||||
|                              PropertyName="Metadata.Album" |  | ||||||
|                              Width="0.95*"> |  | ||||||
|                             <dg:DataGridColumn.CellTemplate> |  | ||||||
|                                 <DataTemplate> |  | ||||||
|                                     <Label |  | ||||||
|                                          LineBreakMode="TailTruncation" |  | ||||||
|                                          Text="{Binding .}"/> |  | ||||||
|                                 </DataTemplate> |  | ||||||
|                             </dg:DataGridColumn.CellTemplate> |  | ||||||
|                         </dg:DataGridColumn> |  | ||||||
|                         <dg:DataGridColumn |  | ||||||
|                              Title="Artist" |  | ||||||
|                              PropertyName="Metadata.Artist" |  | ||||||
|                              Width="1*"> |  | ||||||
|                             <dg:DataGridColumn.CellTemplate> |  | ||||||
|                                 <DataTemplate> |  | ||||||
|                                     <Label |  | ||||||
|                                          LineBreakMode="TailTruncation" |  | ||||||
|                                          Text="{Binding .}"/> |  | ||||||
|                                 </DataTemplate> |  | ||||||
|                             </dg:DataGridColumn.CellTemplate> |  | ||||||
|                         </dg:DataGridColumn> |  | ||||||
|                     </dg:DataGrid.Columns> |  | ||||||
|                     <dg:DataGrid.RowsTextColorPalette> |  | ||||||
|                         <dg:PaletteCollection> |  | ||||||
|                             <Color>White</Color> |  | ||||||
|                         </dg:PaletteCollection> |  | ||||||
|                     </dg:DataGrid.RowsTextColorPalette> |  | ||||||
|                     <dg:DataGrid.RowsBackgroundColorPalette> |  | ||||||
|                         <dg:PaletteCollection> |  | ||||||
|                             <Color>Transparent</Color> |  | ||||||
|                         </dg:PaletteCollection> |  | ||||||
|                     </dg:DataGrid.RowsBackgroundColorPalette> |  | ||||||
|                 </dg:DataGrid><!-- <library:Library |  | ||||||
|                      ItemsSource="{Binding Queue}" |                      ItemsSource="{Binding Queue}" | ||||||
|                      SelectedItem="{Binding SelectedSong}" |                      SelectedItem="{Binding SelectedSong}" | ||||||
|                      ItemDoubleClicked="{Binding PlayCommand}"/> --> |                      ItemDoubleClicked="{Binding PlayCommand}"/> | ||||||
|             </StackLayout> |  | ||||||
|         </Grid> |         </Grid> | ||||||
|     </ContentView.Content> |     </ContentView.Content> | ||||||
| </ContentView> | </ContentView> | ||||||
		Reference in New Issue
	
	Block a user