How to refresh a collectionView when click on button - c#

I would like to refresh my collectionView When I click on a button and make the app continue to run while the collectionview is filled
Here is my Xaml :
<CollectionView x:Name="WordSList" ItemsLayout="Vertical" >
<CollectionView.ItemTemplate >
<DataTemplate>
<StackLayout >
<Label Text="{Binding Word1}" />
</StackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
What I would like :
List<MyClass> MyWordsList;
ObservableCollection<MyClass> datasource;
int ndx = 100;
public void OnRefreshing_MyCollection_View()
{
// refresh the collection view without making the app waiting for it to be filled
MyWordsList = await mywordsdatabase.GetWords();
WordSList.ItemsSource = datasource = new ObservableCollection<MyClass (MyWordsList.Take(ndx));
}
Thanks for your help

you can use the RefreshView of Xamarin.Forms like in this example of James Montemagno:
https://devblogs.microsoft.com/xamarin/refreshview-xamarin-forms/
You have a property IsRefreshing which you set on the beginning of your refreshing-method. After refreshing you set it to false.
<RefreshView IsRefreshing="{Binding IsRefreshing}"
Command="{Binding RefreshCommand}">
<CollectionView ItemsSource="{Binding Items}">
<CollectionView.ItemsLayout>
<LinearItemsLayout Orientation="Vertical"/>
</CollectionView.ItemsLayout>
<!-- Add ItemTemplate Here -->
</CollectionView>
</RefreshView>
void ExecuteRefreshCommand()
{
Items.Clear();
Items.Add(new Item { Text = "Refreshed Data", Description = "Whoa!" });
// Stop refreshing
IsRefreshing = false;
}
In the example its an drag-down-element in your collection view. But you can also do this with a button event and an async method to load your data.

Related

MAUI ListView Filtering is too slow on Android Phone

.Net MAUI, I have a searchbar and a CollectionView (With only 50 CityNames from DB).
Filtering of the collectionview Items on TextChanged property of SearchBar is very slow.
I can't even type properly.
I have tried a lot things like making the calls Async, Converting the CollectionView to ListView etc. but nothing worked.
works okay on the windows app but on android it is giving me hard time.
and my android device is pretty new and powerful, so no issues with the phone.
Below is the Xaml
<StackLayout HorizontalOptions="FillAndExpand" Orientation="Vertical" Margin="5">
<Frame BackgroundColor="MintCream" Padding="10"
CornerRadius="20">
<VerticalStackLayout>
<SearchBar x:Name="FromSearchBar" TextChanged="FromSearchBar_TextChanged" Text="{Binding FromSearchText}" Placeholder="From City" HorizontalOptions="FillAndExpand" />
</VerticalStackLayout>
</Frame>
<CollectionView x:Name="FromColl" ItemsSource="{Binding Cities}" IsVisible="true">
<CollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout Padding="10">
<Label Grid.Column="1"
Text="{Binding FullCityName}"
FontAttributes="Bold" />
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
</StackLayout>
C# Code Behind:
public MainPage()
{
InitializeComponent();
ViewModel = new NewItemViewModel();
this.BindingContext = ViewModel;
}
public NewItemViewModel ViewModel { get; set; }
private void FromSearchBar_TextChanged(object sender, TextChangedEventArgs e)
{
var searchBar = (SearchBar)sender;
ViewModel.Cities = new ObservableCollection<CityList>(CityRepository.GetAllFromDbAsync(searchBar.Text));
ViewModel.FromListViewVisible = true;
}
Repository For DB:
public static List<CityList> GetAllFromDbAsync(string str)
{
try
{
var rtdb = new RTDatabase();
if (string.IsNullOrEmpty(str))
return rtdb.GetItems().Result.Take(50).ToList();
else
return rtdb.GetItems().Result.Where(a => a.CityName.ToLower().StartsWith(str.ToLower())).Take(50).ToList();
}
catch (Exception ex)
{
LogError.log("CityRepository.cs - GetAllFromDbAsync - " + ex.Message);
return new List<CityList>();
}
}
public Task<List<CityList>> GetItems()
{
return Database.Table<CityList>().ToListAsync();
}

CarouselView PositionChange event not get called in ContentView page Xamairn.Forms (Android)

Currently, I have updated Xamarin.Forms version in my project to 5.0.0.2083. After that, I am facing some weird issues in CarouselView control. I have used Carousel and IndicatorView controls in one place, and the issue I am facing is IndicatorView is not working on an Android device.
It's working fine in iOS, the issue comes only from Android. To fix this problem I have tried to use the PositionChanged event of CarouselView but that also works in iOS only and not in Android. I have tried many things but none of them worked.
Here is my code:
<CarouselView x:Name="creditCardsList"
ItemsSource="{Binding CardList}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Loop="False"
HorizontalScrollBarVisibility="Never"
Margin="20,0"
IsScrollAnimated="True"
ItemsUpdatingScrollMode="KeepItemsInView"
Position="{Binding CarouselPosition}"
HeightRequest="{StaticResource HeightWidth160}"
PositionChanged="creditCardsList_PositionChanged"
IndicatorView="CardIndicatorView">
<CarouselView.ItemTemplate>
<DataTemplate>
<!--UI that I want to display-->
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView x:Name="CardIndicatorView"
VerticalOptions="End"
Margin="{DynamicResource MarginPadding00_10_00_10}"
IndicatorColor="Gray"
SelectedIndicatorColor="{StaticResource action_button_color}"
IndicatorsShape="Square"
ItemsSource="{Binding CardList}"/>
Does anyone know any workaround for this? I just want to change Indicators as I swipe items in CarouselView. Any help would be appreciated!
I test with Xamarin.Forms 5.0.0.2083 on Android , IndicatorView and event PositionChanged works fine ,see the following screenshot below.
Update
Here is my testing code
xaml
<StackLayout>
<CarouselView x:Name="creditCardsList"
ItemsSource="{Binding CardList}"
HorizontalOptions="FillAndExpand"
VerticalOptions="FillAndExpand"
Loop="False"
HorizontalScrollBarVisibility="Never"
Margin="20,0"
IsScrollAnimated="True"
ItemsUpdatingScrollMode="KeepItemsInView"
HeightRequest="200"
PositionChanged="creditCardsList_PositionChanged"
IndicatorView="CardIndicatorView">
<CarouselView.ItemTemplate>
<DataTemplate>
<Image Source="dog.png"/>
</DataTemplate>
</CarouselView.ItemTemplate>
</CarouselView>
<IndicatorView
x:Name="CardIndicatorView"
VerticalOptions="End"
Margin="20"
IndicatorColor="Gray"
SelectedIndicatorColor="Red"
IndicatorsShape="Square"
ItemsSource="{Binding CardList}"/>
</StackLayout>
code behind
public class Model
{
public List<string> CardList { get; set; }
}
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class Page1 : ContentPage
{
public Page1()
{
InitializeComponent();
Model model = new Model();
model.CardList = new List<string> { "1", "2", "3" };
this.BindingContext = model;
}
private void creditCardsList_PositionChanged(object sender, PositionChangedEventArgs e)
{
}
}

Xamarin: Change value of GridItemLayout in codebehind

<CollectionView Grid.Row="2" Grid.Column="0" x:Name="collectionViewItemsLayout" ItemsSource="{Binding BaseCustomersCards}" ItemTemplate="{StaticResource CustomerCardTemplateSelector}" >
<CollectionView.ItemsLayout>
<GridItemsLayout Orientation="Vertical" Span="5" />
</CollectionView.ItemsLayout>
</CollectionView>
I've got this collectionview but am attempting to change the span for phone-tablet. Default is 5 but phone value should be 3.
var idiom = DeviceInfo.Idiom;
if (idiom == DeviceIdiom.Phone)
{
collectionViewItemsLayout.SetValue(GridItemsLayout.SpanProperty, 3);
}
I made this in the code-behind to change it, the method triggers but doesn't change anything. I've tried to put the 3 as a string and as pure value. I've also attempted to put the x:name in the attribute but it cannot go there.
Works by creating a new GridItem and setting it instead
if (idiom == DeviceIdiom.Phone)
{
var grid = new GridItemsLayout(ItemsLayoutOrientation.Vertical)
{
Span = 3,
};
collectionViewItemsLayout.SetValue(CollectionView.ItemsLayoutProperty, grid);
}

How to pass a ListView value to another page using an item button click?

I have ListView which is populating Id based on username:
<Entry Text="{Binding username, Mode=TwoWay}"/>
<Button Command="{Binding SearchCommand}" />
<ListView ItemsSource="{Binding SearchId}"
HasUnevenRows="False"
x:Name="list"
ItemTapped="LstItems_OnItemTapped">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell >
<StackLayout Orientation="Vertical" >
<Label x:Name="ident"
Text="{Binding Id}"></Label>
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
private async void LstItems_OnItemTapped(object sender, ItemTappedEventArgs e)
{
var item = (UserDetail)e.Item;
var newpage = new Contact(item.Id);
await Navigation.PushAsync(newpage);
}
public Command SearchCommand
{
get
{
return new Command(async () =>
{
var employeesServices = new EmployeesServices();
SearchId= await employeesServices.GetUserDetailAsync(_username);
});
}
}
private List<UserDetail> _SearchId;
public List<UserDetail> SearchId
{
get { return _SearchId; }
set
{
_SearchId = value;
OnPropertChanged();
}
}
I can successfully pass the id to another page, now I have another issue, I can only pass Id from listview to another page when I tap on the listview.
Is it possible if I click on button Id directly pass on next page without tap on ListView?
You can use SelectedItem inside your List View like this:
<ListView ItemsSource="{Binding SearchId}" HasUnevenRows="False" x:Name="list" ItemTapped="LstItems_OnItemTapped" SelectedItem="{Binding SelectedListItem,Mode=TwoWay}">
After using this you will have current selected item of your list and you can pass that to any page!
Hope this may solve your issue.

Windows 10 phone How add Checkbox to the ListView

I want add Text to ListView element when i press button:
private void button_Click(object sender, RoutedEventArgs e)
{
listView.Items.Add(textBox.Text);
}
It works but i got:
Element1
Element2
Element3
But i want to see something like:
[]Element1
[]Element2
Where [ ] is checkbox :)
My xaml:
<ListView x:Name="listView" HorizontalAlignment="Left" Height="406" Margin="10,224,0,0" VerticalAlignment="Top" Width="340" />
I don't see option CheckBoxes True/False in my xaml Properties
XAML
Modify the listView item template to add your custom layout.
Add a data binding to the set the text
<ListView x:Name="listView" HorizontalAlignment="Left" VerticalAlignment="Stretch" Width="340">
<ListView.ItemTemplate>
<DataTemplate>
<WrapPanel>
<CheckBox/>
<Label Content="{Binding Text}"/>
</WrapPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Code Behind
declare this class somewhere
public class Row
{
private string text;
public Row (string text)
{
this.text = text;
}
public string Text
{
get { return text; }
set { text = value; }
}
}
Add this code to the constructor of the code associated with the xaml
ObservableCollection<Row> list = new ObservableCollection<Row>();
listView.ItemsSource = list;
How to add items/text to the listView
list.Add(new Row("Hello"));
list.Add(new Row("World"));
Hope this helps!

Categories