mirror of
				https://github.com/Nioux/AideDeJeu.git
				synced 2025-10-31 07:26:09 +00:00 
			
		
		
		
	Chargement en async + indicateur d'activité
This commit is contained in:
		
							parent
							
								
									bfe8f0d81f
								
							
						
					
					
						commit
						5d28b9b469
					
				
					 6 changed files with 145 additions and 130 deletions
				
			
		|  | @ -1,11 +1,11 @@ | |||
| #pragma warning disable 1591 | ||||
| //------------------------------------------------------------------------------ | ||||
| // <auto-generated> | ||||
| //     Ce code a été généré par un outil. | ||||
| //     Version du runtime :4.0.30319.42000 | ||||
| //     This code was generated by a tool. | ||||
| //     Runtime Version:4.0.30319.42000 | ||||
| // | ||||
| //     Les modifications apportées à ce fichier peuvent provoquer un comportement incorrect et seront perdues si | ||||
| //     le code est régénéré. | ||||
| //     Changes to this file may cause incorrect behavior and will be lost if | ||||
| //     the code is regenerated. | ||||
| // </auto-generated> | ||||
| //------------------------------------------------------------------------------ | ||||
| 
 | ||||
|  |  | |||
|  | @ -7,8 +7,12 @@ | |||
|   <PropertyGroup Condition="'$(Configuration)|$(Platform)'=='Debug|AnyCPU'"> | ||||
|     <DebugType>pdbonly</DebugType> | ||||
|     <DebugSymbols>true</DebugSymbols> | ||||
|     <LangVersion>Latest</LangVersion> | ||||
|   </PropertyGroup> | ||||
| 
 | ||||
|   <PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' "> | ||||
|     <LangVersion>Latest</LangVersion> | ||||
|   </PropertyGroup> | ||||
|   <ItemGroup> | ||||
|     <EmbeddedResource Remove="Resources\AdJTheme.xaml" /> | ||||
|   </ItemGroup> | ||||
|  |  | |||
|  | @ -8,13 +8,15 @@ using System.Diagnostics; | |||
| using System.Linq; | ||||
| using System.Text; | ||||
| using System.Windows.Input; | ||||
| using System.Threading; | ||||
| using System.Threading.Tasks; | ||||
| 
 | ||||
| namespace AideDeJeu.ViewModels | ||||
| { | ||||
|     public abstract class FilterViewModel : BaseViewModel | ||||
|     { | ||||
|         public ICommand LoadItemsCommand { get; protected set; } | ||||
|         public abstract IEnumerable<Item> FilterItems(IEnumerable<Item> items); | ||||
|         public abstract Task<IEnumerable<Item>> FilterItems(IEnumerable<Item> items, CancellationToken token = default); | ||||
|         public abstract IEnumerable<Filter> Filters { get; } | ||||
|         private string _SearchText = ""; | ||||
|         public string SearchText | ||||
|  | @ -77,7 +79,7 @@ namespace AideDeJeu.ViewModels | |||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if(Index >= 0 && Index < KeyValues.Count) | ||||
|                 if (Index >= 0 && Index < KeyValues.Count) | ||||
|                 { | ||||
|                     return KeyValues[Index].Key; | ||||
|                 } | ||||
|  | @ -94,7 +96,7 @@ namespace AideDeJeu.ViewModels | |||
|         { | ||||
|             get | ||||
|             { | ||||
|                 if(_Filters == null) | ||||
|                 if (_Filters == null) | ||||
|                 { | ||||
|                     _Filters = new List<Filter>() | ||||
|                     { | ||||
|  | @ -111,29 +113,31 @@ namespace AideDeJeu.ViewModels | |||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public override IEnumerable<Item> FilterItems(IEnumerable<Item> items) | ||||
|         public override async Task<IEnumerable<Item>> FilterItems(IEnumerable<Item> items, CancellationToken token = default) | ||||
|         { | ||||
|             var classe = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Class).SelectedKey ?? ""; | ||||
|             var niveauMin = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MinLevel).SelectedKey ?? "0"; | ||||
|             var niveauMax = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MaxLevel).SelectedKey ?? "9"; | ||||
|             var ecole = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.School).SelectedKey ?? ""; | ||||
|             var rituel = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Ritual).SelectedKey ?? ""; | ||||
|             var source = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Source).SelectedKey ?? ""; | ||||
|             return await Task.Run(() => | ||||
|             { | ||||
|                 var classe = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Class).SelectedKey ?? ""; | ||||
|                 var niveauMin = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MinLevel).SelectedKey ?? "0"; | ||||
|                 var niveauMax = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MaxLevel).SelectedKey ?? "9"; | ||||
|                 var ecole = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.School).SelectedKey ?? ""; | ||||
|                 var rituel = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Ritual).SelectedKey ?? ""; | ||||
|                 var source = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Source).SelectedKey ?? ""; | ||||
|                 token.ThrowIfCancellationRequested(); | ||||
|                 return items.Where(item => | ||||
|                 { | ||||
|                     var spell = item as Spell; | ||||
|                     return (int.Parse(spell.Level) >= int.Parse(niveauMin)) && | ||||
|                         (int.Parse(spell.Level) <= int.Parse(niveauMax)) && | ||||
|                         spell.Type.ToLower().Contains(ecole.ToLower()) && | ||||
|                         spell.Source.Contains(source) && | ||||
|                         spell.Source.Contains(classe) && | ||||
|                         spell.Type.Contains(rituel) && | ||||
|                         spell.NamePHB.ToLower().Contains(SearchText.ToLower()); | ||||
|                 }).OrderBy(spell => spell.NamePHB) | ||||
|                             .AsEnumerable(); | ||||
|             }, token); | ||||
| 
 | ||||
|             return items | ||||
|                     .Where(item => | ||||
|                     { | ||||
|                         var spell = item as Spell; | ||||
|                         return (int.Parse(spell.Level) >= int.Parse(niveauMin)) && | ||||
|                             (int.Parse(spell.Level) <= int.Parse(niveauMax)) && | ||||
|                             spell.Type.ToLower().Contains(ecole.ToLower()) && | ||||
|                             spell.Source.Contains(source) && | ||||
|                             spell.Source.Contains(classe) && | ||||
|                             spell.Type.Contains(rituel) && | ||||
|                             spell.NamePHB.ToLower().Contains(SearchText.ToLower()); | ||||
|                     }) | ||||
|                     .OrderBy(spell => spell.NamePHB) | ||||
|                     .ToList(); | ||||
|         } | ||||
| 
 | ||||
|         public abstract List<KeyValuePair<string, string>> Classes { get; } | ||||
|  | @ -343,19 +347,30 @@ namespace AideDeJeu.ViewModels | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public override IEnumerable<Item> FilterItems(IEnumerable<Item> items) | ||||
|         public override async Task<IEnumerable<Item>> FilterItems(IEnumerable<Item> items, CancellationToken token = default) | ||||
|         { | ||||
|             var powerComparer = new PowerComparer(); | ||||
|             return await Task.Run(() => | ||||
|             { | ||||
|                 var powerComparer = new PowerComparer(); | ||||
| 
 | ||||
|             //var category = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Category).SelectedKey ?? ""; | ||||
|             var type = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Type).SelectedKey ?? ""; | ||||
|             var minPower = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MinPower).SelectedKey ?? "0 (0 PX)"; | ||||
|             var maxPower = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MaxPower).SelectedKey ?? "30 (155000 PX)"; | ||||
|             var size = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Size).SelectedKey ?? ""; | ||||
|             //var legendary = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Legendary).SelectedKey ?? ""; | ||||
|             var source = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Source).SelectedKey ?? ""; | ||||
|                 //var category = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Category).SelectedKey ?? ""; | ||||
|                 var type = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Type).SelectedKey ?? ""; | ||||
|                 token.ThrowIfCancellationRequested(); | ||||
| 
 | ||||
|             return items.Where(item => | ||||
|                 var minPower = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MinPower).SelectedKey ?? "0 (0 PX)"; | ||||
|                 token.ThrowIfCancellationRequested(); | ||||
| 
 | ||||
|                 var maxPower = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.MaxPower).SelectedKey ?? "30 (155000 PX)"; | ||||
|                 token.ThrowIfCancellationRequested(); | ||||
| 
 | ||||
|                 var size = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Size).SelectedKey ?? ""; | ||||
|                 token.ThrowIfCancellationRequested(); | ||||
|                 //var legendary = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Legendary).SelectedKey ?? ""; | ||||
| 
 | ||||
|                 var source = Filters.SingleOrDefault(filter => filter.Key == FilterKeys.Source).SelectedKey ?? ""; | ||||
|                 token.ThrowIfCancellationRequested(); | ||||
| 
 | ||||
|                 return items.Where(item => | ||||
|                 { | ||||
|                     var monster = item as Monster; | ||||
|                     return monster.Type.Contains(type) && | ||||
|  | @ -365,8 +380,10 @@ namespace AideDeJeu.ViewModels | |||
|                         powerComparer.Compare(monster.Challenge, maxPower) <= 0 && | ||||
|                         monster.NamePHB.ToLower().Contains(SearchText.ToLower()); | ||||
|                 }) | ||||
|                 .OrderBy(monster => monster.NamePHB) | ||||
|                 .ToList(); | ||||
|                     .OrderBy(monster => monster.NamePHB) | ||||
|                             .AsEnumerable(); | ||||
|             }, token); | ||||
| 
 | ||||
|         } | ||||
| 
 | ||||
|         public abstract List<KeyValuePair<string, string>> Categories { get; } | ||||
|  |  | |||
|  | @ -8,15 +8,18 @@ using System.Diagnostics; | |||
| using System.Threading.Tasks; | ||||
| using System.Windows.Input; | ||||
| using Xamarin.Forms; | ||||
| using System.Threading; | ||||
| 
 | ||||
| namespace AideDeJeu.ViewModels | ||||
| { | ||||
|     public abstract class ItemsViewModel : BaseViewModel | ||||
|     { | ||||
|         CancellationTokenSource cancellationTokenSource; | ||||
| 
 | ||||
|         public ItemsViewModel(ItemSourceType itemSourceType) | ||||
|         { | ||||
|             this.ItemSourceType = itemSourceType; | ||||
|             LoadItemsCommand = new Command(() => ExecuteLoadItemsCommand()); | ||||
|             LoadItemsCommand = new Command(async () => await ExecuteLoadItemsCommandAsync()); | ||||
|         } | ||||
|         public ICommand LoadItemsCommand { get; protected set; } | ||||
|         //public abstract void ExecuteLoadItemsCommand(); | ||||
|  | @ -66,26 +69,28 @@ namespace AideDeJeu.ViewModels | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         public void ExecuteLoadItemsCommand() | ||||
|         async Task LoadItemsAsync(CancellationToken token = default) | ||||
|         { | ||||
|             if (IsBusy) | ||||
|                 return; | ||||
| 
 | ||||
|             IsBusy = true; | ||||
| 
 | ||||
|             Main.IsLoading = true; | ||||
|             try | ||||
|             { | ||||
|                 Main.Items.Clear(); | ||||
| 
 | ||||
|                 var filterViewModel = Main.GetFilterViewModel(ItemSourceType); | ||||
|                 var items = filterViewModel.FilterItems(AllItems); | ||||
| 
 | ||||
|                 foreach (var item in items) | ||||
|                 var items = await filterViewModel.FilterItems(AllItems, token); | ||||
|                 await Task.Run(() => | ||||
|                 { | ||||
|                     Main.Items.Add(item); | ||||
|                 } | ||||
|                     Main.Items.Clear(); | ||||
|                     foreach (var item in items) | ||||
|                     { | ||||
|                         token.ThrowIfCancellationRequested(); | ||||
|                         Main.Items.Add(item); | ||||
|                     } | ||||
|                 }); | ||||
| 
 | ||||
|                 //On arrete le loading ici car on annule toujours avant de lancer une nouvelle opération | ||||
|                 Main.IsLoading = false; | ||||
|             } | ||||
|             catch (Exception ex) | ||||
|             catch (OperationCanceledException ex) | ||||
|             { | ||||
|                 Debug.WriteLine(ex); | ||||
|             } | ||||
|  | @ -95,6 +100,14 @@ namespace AideDeJeu.ViewModels | |||
|             } | ||||
|         } | ||||
| 
 | ||||
| 
 | ||||
|         public async Task ExecuteLoadItemsCommandAsync() | ||||
|         { | ||||
|             if (cancellationTokenSource != null) | ||||
|             { | ||||
|                 cancellationTokenSource.Cancel(); | ||||
|             } | ||||
|             cancellationTokenSource = new CancellationTokenSource(); | ||||
|             await LoadItemsAsync(cancellationTokenSource.Token); | ||||
|         } | ||||
|     } | ||||
| } | ||||
|  |  | |||
|  | @ -52,6 +52,13 @@ namespace AideDeJeu.ViewModels | |||
|             } | ||||
|         } | ||||
| 
 | ||||
|         private bool _isLoading; | ||||
|         public bool IsLoading | ||||
|         { | ||||
|             get => _isLoading; | ||||
|             set => SetProperty(ref _isLoading, value); | ||||
|         } | ||||
| 
 | ||||
|         public Dictionary<ItemSourceType, Lazy<ItemsViewModel>> AllItemsViewModel = new Dictionary<ItemSourceType, Lazy<ItemsViewModel>>() | ||||
|         { | ||||
|             { ItemSourceType.SpellVF, new Lazy<ItemsViewModel>(() => new SpellsViewModel(ItemSourceType.SpellVF)) }, | ||||
|  | @ -116,21 +123,21 @@ namespace AideDeJeu.ViewModels | |||
| 
 | ||||
|         public MainViewModel() | ||||
|         { | ||||
|             LoadItemsCommand = new Command(() => | ||||
|             LoadItemsCommand = new Command(async () => | ||||
|                 { | ||||
|                     GetItemsViewModel(ItemSourceType).ExecuteLoadItemsCommand(); | ||||
|                     await GetItemsViewModel(ItemSourceType).ExecuteLoadItemsCommandAsync(); | ||||
|                 }); | ||||
|             GotoItemCommand = new Command<Item>(async (item) => await GetItemsViewModel(ItemSourceType).ExecuteGotoItemCommandAsync(item)); | ||||
|             SwitchToSpells = new Command(() => ItemSourceType = (ItemSourceType & ~ ItemSourceType.Monster) | ItemSourceType.Spell); | ||||
|             SwitchToSpells = new Command(() => ItemSourceType = (ItemSourceType & ~ItemSourceType.Monster) | ItemSourceType.Spell); | ||||
|             SwitchToMonsters = new Command(() => ItemSourceType = (ItemSourceType & ~ItemSourceType.Spell) | ItemSourceType.Monster); | ||||
|             SwitchToVF = new Command(() => ItemSourceType = (ItemSourceType & ~ItemSourceType.VO & ~ItemSourceType.HD) | ItemSourceType.VF); | ||||
|             SwitchToVO = new Command(() => ItemSourceType = (ItemSourceType & ~ItemSourceType.VF & ~ItemSourceType.HD) | ItemSourceType.VO); | ||||
|             SwitchToHD = new Command(() => ItemSourceType = (ItemSourceType & ~ItemSourceType.VF & ~ItemSourceType.VO) | ItemSourceType.HD); | ||||
|             AboutCommand = new Command(async() => await Main.Navigator.GotoAboutPageAsync()); | ||||
|             SearchCommand = new Command<string>((text) => | ||||
|             AboutCommand = new Command(async () => await Main.Navigator.GotoAboutPageAsync()); | ||||
|             SearchCommand = new Command<string>(async (text) => | ||||
|                 { | ||||
|                     GetFilterViewModel(ItemSourceType).SearchText = text; | ||||
|                     GetItemsViewModel(ItemSourceType).ExecuteLoadItemsCommand(); | ||||
|                     await GetItemsViewModel(ItemSourceType).ExecuteLoadItemsCommandAsync(); | ||||
|                 }); | ||||
|         } | ||||
|     } | ||||
|  |  | |||
|  | @ -1,45 +1,30 @@ | |||
| <?xml version="1.0" encoding="utf-8" ?> | ||||
| <MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" | ||||
|                 xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" | ||||
|                 xmlns:local="clr-namespace:AideDeJeu.Views" | ||||
|                 xmlns:tools="clr-namespace:AideDeJeu.Tools" | ||||
|                 x:Class="AideDeJeu.Views.MainPage" | ||||
|                 x:Name="This" | ||||
|                 IsPresented="False" | ||||
|                 Title=""> | ||||
| <?xml version="1.0" encoding="utf-8"?> | ||||
| <MasterDetailPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" xmlns:local="clr-namespace:AideDeJeu.Views" xmlns:tools="clr-namespace:AideDeJeu.Tools" x:Class="AideDeJeu.Views.MainPage" x:Name="This" IsPresented="False" Title=""> | ||||
|     <MasterDetailPage.Resources> | ||||
|         <ResourceDictionary> | ||||
|             <tools:ItemSourceTypeToStringConverter  | ||||
|                 x:Key="ItemSourceTypeToTitleConverter"  | ||||
|                 SpellVF="Sorts"  | ||||
|                 SpellVO="Spells"  | ||||
|                 SpellHD="Sorts (H&D)"  | ||||
|                 MonsterVF="Monstres"  | ||||
|                 MonsterVO="Monsters"  | ||||
|                 MonsterHD="Créatures (H&D)"  | ||||
|                 /> | ||||
|             <tools:ItemSourceTypeToItemsConverter  | ||||
|                 x:Key="ItemSourceTypeToItemsConverter" /> | ||||
|             <tools:ItemSourceTypeToFilterConverter  | ||||
|                 x:Key="ItemSourceTypeToFilterConverter" /> | ||||
|             <tools:ItemSourceTypeToStringConverter x:Key="ItemSourceTypeToTitleConverter" SpellVF="Sorts" SpellVO="Spells" SpellHD="Sorts (H&D)" MonsterVF="Monstres" MonsterVO="Monsters" MonsterHD="Créatures (H&D)" /> | ||||
|             <tools:ItemSourceTypeToItemsConverter x:Key="ItemSourceTypeToItemsConverter" /> | ||||
|             <tools:ItemSourceTypeToFilterConverter x:Key="ItemSourceTypeToFilterConverter" /> | ||||
|         </ResourceDictionary> | ||||
|     </MasterDetailPage.Resources> | ||||
|     <MasterDetailPage.Master> | ||||
|         <ContentPage Title=" "> | ||||
|             <ListView ItemsSource="{Binding ItemSourceType, Converter={StaticResource ItemSourceTypeToFilterConverter}}" HasUnevenRows="True" RowHeight="-1" SeparatorVisibility="None" IsPullToRefreshEnabled="False" > | ||||
|                 <ListView.ItemTemplate> | ||||
|                     <DataTemplate> | ||||
|                         <ViewCell> | ||||
|                             <ViewCell.View> | ||||
|                                 <StackLayout Margin="10,5,10,0" Padding="0" Spacing="0"> | ||||
|                                     <Label BindingContext="{Binding}" Text="{Binding Name}" Style="{StaticResource Key=subsubsection}" /> | ||||
|                                     <Picker HorizontalOptions="FillAndExpand" ItemsSource="{Binding KeyValues, Mode=OneWay}" ItemDisplayBinding="{Binding Value, Mode=OneWay}" SelectedIndex="{Binding Index}" /> | ||||
|                                 </StackLayout> | ||||
|                             </ViewCell.View> | ||||
|                         </ViewCell> | ||||
|                     </DataTemplate> | ||||
|                 </ListView.ItemTemplate> | ||||
|             </ListView> | ||||
|             <AbsoluteLayout> | ||||
|                 <ListView ItemsSource="{Binding ItemSourceType, Converter={StaticResource ItemSourceTypeToFilterConverter}}" HasUnevenRows="True" RowHeight="-1" SeparatorVisibility="None" IsPullToRefreshEnabled="False"> | ||||
|                     <ListView.ItemTemplate> | ||||
|                         <DataTemplate> | ||||
|                             <ViewCell> | ||||
|                                 <ViewCell.View> | ||||
|                                     <StackLayout Margin="10,5,10,0" Padding="0" Spacing="0"> | ||||
|                                         <Label BindingContext="{Binding}" Text="{Binding Name}" Style="{StaticResource Key=subsubsection}" /> | ||||
|                                         <Picker HorizontalOptions="FillAndExpand" ItemsSource="{Binding KeyValues, Mode=OneWay}" ItemDisplayBinding="{Binding Value, Mode=OneWay}" SelectedIndex="{Binding Index}" /> | ||||
|                                     </StackLayout> | ||||
|                                 </ViewCell.View> | ||||
|                             </ViewCell> | ||||
|                         </DataTemplate> | ||||
|                     </ListView.ItemTemplate> | ||||
|                 </ListView> | ||||
|             </AbsoluteLayout> | ||||
|         </ContentPage> | ||||
|     </MasterDetailPage.Master> | ||||
|     <MasterDetailPage.Detail> | ||||
|  | @ -54,38 +39,27 @@ | |||
|                         <ToolbarItem Name="VO" Text="VO AideDD/SRD" Order="Secondary" Command="{Binding SwitchToVO}" /> | ||||
|                         <ToolbarItem Name="HD" Text="VF H&D" Order="Secondary" Command="{Binding SwitchToHD}" /> | ||||
|                     </ContentPage.ToolbarItems> | ||||
|                     <StackLayout Orientation="Vertical"> | ||||
|                         <SearchBar x:Name="SearchBar" SearchCommand="{Binding SearchCommand}" SearchCommandParameter="{Binding Text, Source={x:Reference SearchBar}}"> | ||||
|                             <SearchBar.Behaviors> | ||||
|                                 <tools:TextChangedBehavior /> | ||||
|                             </SearchBar.Behaviors> | ||||
|                         </SearchBar> | ||||
| 
 | ||||
|                         <ListView  | ||||
|                             x:Name="ItemsListView"  | ||||
|                             ItemsSource="{Binding Items}"  | ||||
|                             VerticalOptions="FillAndExpand" | ||||
|                             HasUnevenRows="true" | ||||
|                             IsRefreshing="{Binding IsBusy, Mode=OneWay}" | ||||
|                             CachingStrategy="RecycleElement" | ||||
|                             SelectedItem="{Binding SelectedItem}" | ||||
|                             ItemTapped="ItemsListView_ItemTapped"> | ||||
| 
 | ||||
|                             <ListView.ItemTemplate> | ||||
|                                 <DataTemplate> | ||||
|                                     <ViewCell> | ||||
|                                         <StackLayout Padding="10"> | ||||
|                                             <Label  | ||||
|                                                 Text="{Binding NamePHB}"  | ||||
|                                                 LineBreakMode="NoWrap"  | ||||
|                                                 Style="{DynamicResource subsubsection}"  | ||||
|                                                 FontSize="16" /> | ||||
|                                         </StackLayout> | ||||
|                                     </ViewCell> | ||||
|                                 </DataTemplate> | ||||
|                             </ListView.ItemTemplate> | ||||
|                         </ListView> | ||||
|                     </StackLayout> | ||||
|                     <AbsoluteLayout> | ||||
|                         <StackLayout Orientation="Vertical"> | ||||
|                             <SearchBar x:Name="SearchBar" SearchCommand="{Binding SearchCommand}" SearchCommandParameter="{Binding Text, Source={x:Reference SearchBar}}"> | ||||
|                                 <SearchBar.Behaviors> | ||||
|                                     <tools:TextChangedBehavior /> | ||||
|                                 </SearchBar.Behaviors> | ||||
|                             </SearchBar> | ||||
|                             <ListView x:Name="ItemsListView" ItemsSource="{Binding Items}" VerticalOptions="FillAndExpand" HasUnevenRows="true" IsRefreshing="{Binding IsBusy, Mode=OneWay}" CachingStrategy="RecycleElement" SelectedItem="{Binding SelectedItem}" ItemTapped="ItemsListView_ItemTapped"> | ||||
|                                 <ListView.ItemTemplate> | ||||
|                                     <DataTemplate> | ||||
|                                         <ViewCell> | ||||
|                                             <StackLayout Padding="10"> | ||||
|                                                 <Label Text="{Binding NamePHB}" LineBreakMode="NoWrap" Style="{DynamicResource subsubsection}" FontSize="16" /> | ||||
|                                             </StackLayout> | ||||
|                                         </ViewCell> | ||||
|                                     </DataTemplate> | ||||
|                                 </ListView.ItemTemplate> | ||||
|                             </ListView> | ||||
|                         </StackLayout> | ||||
|                         <ActivityIndicator AbsoluteLayout.LayoutBounds="0.5,0.5" AbsoluteLayout.LayoutFlags="XProportional, YProportional" IsRunning="{x:Binding IsLoading}" Color="Olive" /> | ||||
|                     </AbsoluteLayout> | ||||
|                 </ContentPage> | ||||
|             </x:Arguments> | ||||
|         </NavigationPage> | ||||
|  |  | |||
		Loading…
	
	Add table
		Add a link
		
	
		Reference in a new issue
	
	 yassine benabbas
						yassine benabbas