From 2a2759d74ee20a0f0ae4fa2807a251894b430252 Mon Sep 17 00:00:00 2001 From: "progress\\marchev" Date: Wed, 25 Mar 2020 16:34:15 +0200 Subject: [PATCH 1/2] Fix the LOD command being raised multiple times when in automatic mode. --- .../IncrementalLoading/ManualBatchLoadingProvider.cs | 9 +++++++++ 1 file changed, 9 insertions(+) diff --git a/Controls/Data.UWP/Data/IncrementalLoading/ManualBatchLoadingProvider.cs b/Controls/Data.UWP/Data/IncrementalLoading/ManualBatchLoadingProvider.cs index dc36e32..10ff4a2 100644 --- a/Controls/Data.UWP/Data/IncrementalLoading/ManualBatchLoadingProvider.cs +++ b/Controls/Data.UWP/Data/IncrementalLoading/ManualBatchLoadingProvider.cs @@ -5,6 +5,8 @@ namespace Telerik.Core.Data internal class ManualBatchLoadingProvider : IDisposable, IBatchLoadingProvider { private ICollection loadedItemsCollection; + private BatchLoadingStatus? status; + public ManualBatchLoadingProvider(ICollection loadedItemsCollection) { this.loadedItemsCollection = loadedItemsCollection; @@ -15,6 +17,11 @@ namespace Telerik.Core.Data public bool ShouldRequestItems(int lastRequestedIndex, int bufferSize) { + if (this.status == BatchLoadingStatus.ItemsRequested) + { + return false; + } + return lastRequestedIndex >= this.loadedItemsCollection.Count - bufferSize; } @@ -28,6 +35,8 @@ namespace Telerik.Core.Data public void OnStatusChanged(BatchLoadingStatus status) { + this.status = status; + var handler = this.StatusChanged; if (handler != null) { From 30eda4f99b829659f2af61f2d01e1c6cb13ed533 Mon Sep 17 00:00:00 2001 From: "progress\\marchev" Date: Thu, 26 Mar 2020 12:04:21 +0200 Subject: [PATCH 2/2] Add useful contextual information in command parameter. --- .../ListView/Model/IListView.cs | 2 + .../ListView/Model/ListViewModel.cs | 6 +- .../Controls/ListViewLoadDataUICommand.cs | 4 +- .../ListView/View/RadListView.cs | 5 + .../Services/Commands/LoadMoreDataContext.cs | 10 ++ SDKExamples.UWP/Data/Examples.xml | 1 + .../ListView/LoadOnDemandCommand.xaml | 46 +++++++++ .../ListView/LoadOnDemandCommand.xaml.cs | 97 +++++++++++++++++++ SDKExamples.UWP/SDKExamples.UWP.csproj | 9 +- 9 files changed, 176 insertions(+), 4 deletions(-) create mode 100644 SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml create mode 100644 SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml.cs diff --git a/Controls/DataControls/DataControls.UWP/ListView/Model/IListView.cs b/Controls/DataControls/DataControls.UWP/ListView/Model/IListView.cs index 07385da..41f66b0 100644 --- a/Controls/DataControls/DataControls.UWP/ListView/Model/IListView.cs +++ b/Controls/DataControls/DataControls.UWP/ListView/Model/IListView.cs @@ -19,5 +19,7 @@ namespace Telerik.UI.Xaml.Controls.Data void ScrollToTop(); void SetScrollPosition(RadPoint point, bool updateUI, bool updateScrollViewer); + + object GetDataContext(); } } diff --git a/Controls/DataControls/DataControls.UWP/ListView/Model/ListViewModel.cs b/Controls/DataControls/DataControls.UWP/ListView/Model/ListViewModel.cs index 9b008c8..b59ba35 100644 --- a/Controls/DataControls/DataControls.UWP/ListView/Model/ListViewModel.cs +++ b/Controls/DataControls/DataControls.UWP/ListView/Model/ListViewModel.cs @@ -56,7 +56,8 @@ namespace Telerik.UI.Xaml.Controls.Data { if (this.DataLoadingMode == BatchLoadingMode.Explicit || this.GroupDescriptors.Count > 0) { - return this.View.CommandService.CanExecuteCommand(CommandId.LoadMoreData, new LoadMoreDataContext()); + LoadMoreDataContext context = new LoadMoreDataContext { View = this.View, DataContext = this.View.GetDataContext() }; + return this.View.CommandService.CanExecuteCommand(CommandId.LoadMoreData, context); } } return false; @@ -268,7 +269,8 @@ namespace Telerik.UI.Xaml.Controls.Data if (this.ShouldAutoRequestItems(null)) { - this.View.CommandService.ExecuteCommand(CommandId.LoadMoreData, new LoadMoreDataContext()); + LoadMoreDataContext context = new LoadMoreDataContext { View = this.View, DataContext = this.View.GetDataContext() }; + this.View.CommandService.ExecuteCommand(CommandId.LoadMoreData, context); } // NOTE: If we decide that we won't zero the length of collapsed rows then this 'TotalLineCount - 1' will be incorrect. diff --git a/Controls/DataControls/DataControls.UWP/ListView/View/Controls/ListViewLoadDataUICommand.cs b/Controls/DataControls/DataControls.UWP/ListView/View/Controls/ListViewLoadDataUICommand.cs index 2236a62..eafc6e6 100644 --- a/Controls/DataControls/DataControls.UWP/ListView/View/Controls/ListViewLoadDataUICommand.cs +++ b/Controls/DataControls/DataControls.UWP/ListView/View/Controls/ListViewLoadDataUICommand.cs @@ -53,7 +53,9 @@ namespace Telerik.UI.Xaml.Controls.Data.ListView /// public void Execute(object parameter) { - this.LoadDataControl.Owner.CommandService.ExecuteCommand(Commands.CommandId.LoadMoreData, new LoadMoreDataContext()); + RadListView listView = this.LoadDataControl.Owner; + LoadMoreDataContext context = new LoadMoreDataContext { View = listView, DataContext = listView.DataContext }; + listView.CommandService.ExecuteCommand(Commands.CommandId.LoadMoreData, context); } } } diff --git a/Controls/DataControls/DataControls.UWP/ListView/View/RadListView.cs b/Controls/DataControls/DataControls.UWP/ListView/View/RadListView.cs index 717ed0f..bc5c023 100644 --- a/Controls/DataControls/DataControls.UWP/ListView/View/RadListView.cs +++ b/Controls/DataControls/DataControls.UWP/ListView/View/RadListView.cs @@ -978,6 +978,11 @@ namespace Telerik.UI.Xaml.Controls.Data } } + object IListView.GetDataContext() + { + return this.DataContext; + } + internal void InvalidatePanelMeasure(RadSize radSize) { if (this.contentPanel != null) diff --git a/Controls/DataControls/DataControls.UWP/ListView/View/Services/Commands/LoadMoreDataContext.cs b/Controls/DataControls/DataControls.UWP/ListView/View/Services/Commands/LoadMoreDataContext.cs index 1d56eec..6f8cf3e 100644 --- a/Controls/DataControls/DataControls.UWP/ListView/View/Services/Commands/LoadMoreDataContext.cs +++ b/Controls/DataControls/DataControls.UWP/ListView/View/Services/Commands/LoadMoreDataContext.cs @@ -12,5 +12,15 @@ /// /// The size of the batch. public uint? BatchSize { get; set; } + + /// + /// Gets the underlying data context. + /// + public object DataContext { get; internal set; } + + /// + /// Gets the view to which this context is associated with. + /// + public object View { get; internal set; } } } diff --git a/SDKExamples.UWP/Data/Examples.xml b/SDKExamples.UWP/Data/Examples.xml index 8091581..a5b755b 100644 --- a/SDKExamples.UWP/Data/Examples.xml +++ b/SDKExamples.UWP/Data/Examples.xml @@ -90,6 +90,7 @@ + diff --git a/SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml b/SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml new file mode 100644 index 0000000..30d3a8a --- /dev/null +++ b/SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml @@ -0,0 +1,46 @@ + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + + diff --git a/SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml.cs b/SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml.cs new file mode 100644 index 0000000..e92bfcf --- /dev/null +++ b/SDKExamples.UWP/Examples/ListView/LoadOnDemandCommand.xaml.cs @@ -0,0 +1,97 @@ +using System; +using System.Collections.ObjectModel; +using System.Threading.Tasks; +using Telerik.Core.Data; +using Telerik.UI.Xaml.Controls.Data.ListView.Commands; +using Windows.UI.Xaml.Controls; + +namespace SDKExamples.UWP.Listview +{ + public sealed partial class LoadOnDemandCommand : ExamplePageBase + { + public LoadOnDemandCommand() + { + this.InitializeComponent(); + + this.loadingModeCombo.ItemsSource = Enum.GetValues(typeof(BatchLoadingMode)); + this.loadingModeCombo.SelectedIndex = 0; + + this.ListView.Commands.Add(new CustomLoadOnDemandCommand()); + + this.DataContext = new ViewModel(); + } + + public class ViewModel + { + public ViewModel() + { + this.Items = new ObservableCollection(); + this.AddItems(40); + } + + public ObservableCollection Items { get; } + + public void AddItems(int count) + { + for (int i = 0; i < count; i++) + { + this.Items.Add(this.Items.Count); + } + } + } + + private void SelectionChanged(object sender, SelectionChangedEventArgs e) + { + ComboBox comboBox = (ComboBox)sender; + this.ListView.IncrementalLoadingMode = (BatchLoadingMode)comboBox.SelectedItem; + } + } + + public class CustomLoadOnDemandCommand : LoadMoreDataCommand + { + private int lodCounter; + + public CustomLoadOnDemandCommand() + :base() + { + this.Id = CommandId.LoadMoreData; + } + + public override bool CanExecute(object parameter) + { + LoadMoreDataContext context = (LoadMoreDataContext)parameter; + LoadOnDemandCommand.ViewModel viewModel = (LoadOnDemandCommand.ViewModel)context.DataContext; + + bool canExecute = viewModel.Items.Count < 100; + return canExecute; + } + + public async override void Execute(object parameter) + { + base.Execute(parameter); + + LoadMoreDataContext context = (LoadMoreDataContext)parameter; + LoadOnDemandCommand.ViewModel viewModel = (LoadOnDemandCommand.ViewModel)context.DataContext; + this.lodCounter++; + + if (this.lodCounter % 3 == 0) + { + // If we do not need to get new data asynchronously, we can add the new items right away. + viewModel.AddItems(15); + } + else + { + // If we need to get new data asynchronously, we must manually update the loading status. + + this.Owner.ChangeDataLoadingStatus(BatchLoadingStatus.ItemsRequested); + + // Mimic getting data from server asynchronously. + await Task.Delay(2000); + + viewModel.AddItems(15); + + this.Owner.ChangeDataLoadingStatus(BatchLoadingStatus.ItemsLoaded); + } + } + } +} diff --git a/SDKExamples.UWP/SDKExamples.UWP.csproj b/SDKExamples.UWP/SDKExamples.UWP.csproj index a86952c..9d17ad7 100644 --- a/SDKExamples.UWP/SDKExamples.UWP.csproj +++ b/SDKExamples.UWP/SDKExamples.UWP.csproj @@ -355,6 +355,9 @@ Layouts.xaml + + LoadOnDemandCommand.xaml + LoadOnDemand.xaml @@ -799,6 +802,10 @@ Designer MSBuild:Compile + + MSBuild:Compile + Designer + Designer MSBuild:Compile @@ -972,4 +979,4 @@ --> - \ No newline at end of file +