Hello,
You could reset ItemSource
of the CollectionView when you click the icon button.
Layout(SelectionMode="None"
will make IconClickCommand
be triggered, setting Single
will make SelectedChangedCommand
be triggered, you could choose the way you prefer to)
<CollectionView x:Name="MyCollectionView" ItemsSource="{Binding Items}" SelectionMode="None" SelectionChangedCommand="{Binding SelectedChangedCommand}" SelectionChangedCommandParameter="{Binding SelectedItem, Source={x:Reference MyCollectionView}}" >
<CollectionView.ItemTemplate>
<DataTemplate>
<HorizontalStackLayout>
<CheckBox > </CheckBox>
<ImageButton Source="{Binding Icon}" Command="{Binding IconClickCommand}" ></ImageButton>
<Label Text="{Binding Name}"/>
</HorizontalStackLayout>
</DataTemplate>
</CollectionView.ItemTemplate>
</CollectionView>
BindingContext(ViewModel)
public class TestViewModel
{
public ObservableCollection<Item> Items { get; set; }// default item source
public Command SelectedChangedCommand=> new Command((sender) =>
{// set SelectionMode Single
if (sender !=null)
{
Item item = sender as Item;
if (item.IsLastLevel == false) {
RefreshSourceWithID(item.FolderId); // refresh data when select the item
}
}
});
public TestViewModel()//ctor, set default data
{
Items = new ObservableCollection<Item>();
Items.Add(new Item { FolderId = "0", IsLastLevel = false, Name = "test1", Icon = "type.png", IconAction = () =>
{
RefreshSourceWithID("0");
}
}) ;
Items.Add(new Item { FolderId = "1", IsLastLevel = false, Name = "test2", Icon = "type.png",
IconAction = () =>
{
RefreshSourceWithID("1");
}
});
Items.Add(new Item { FolderId = "2", IsLastLevel = false, Name = "test2", Icon = "type.png" });// if you want to click the button to refresh the data, try to add action, set set SelectionMode None
Items.Add(new Item { FolderId = "3", IsLastLevel = true, Name = "1.txt", Icon = "back.png" });
}
void GoBack(string folderID)
{
Items.Clear();
// Items.Add(...)
}
void RefreshSourceWithID(string folderID)
{
Items.Clear();
// request new data source according to ID, make fake data to simulate this progress
if (folderID == "0")
{
Items.Add(new Item { FolderId = "new 0", Name = "...", Icon = "back.png", IsLastLevel = true, IconAction = () => { GoBack("new 1"); } });// call go back
Items.Add(new Item { FolderId = "new 1", Name = "new test0", Icon = "type.png", IsLastLevel = false });// if you want to click the button to refresh the data, try to add action
}
else
{
Items.Add(new Item { FolderId = "other 0", Name = "other test0", Icon = "type.png", IsLastLevel = false });
Items.Add(new Item { FolderId = "other 1", Name = "other.txt", Icon = "back.png", IsLastLevel = true });
Items.Add(new Item { FolderId = "other 2", Name = "other test2", Icon = "type.png", IsLastLevel = false });
Items.Add(new Item { FolderId = "other 3", Name = "other test3", Icon = "type.png", IsLastLevel = false });
}
}
}
Model
public class Item : INotifyPropertyChanged//Model class
{
public Action IconAction { get; set; }
private bool isLastLevel;
public bool IsLastLevel
{
get => isLastLevel;
set
{
if (isLastLevel != value)
{
isLastLevel = value;
OnPropertyChanged();
}
}
}
public string FolderId { get; set; }
private string icon;
public string Icon
{
get => icon;
set
{
if (icon != value)
{
icon = value;
OnPropertyChanged();
}
}
}
private string name;
public string Name
{
get => name;
set
{
if (name != value)
{
name = value;
OnPropertyChanged();
}
}
}
public Command IconClickCommand => new Command(IconClicked);
public event PropertyChangedEventHandler PropertyChanged;
public void OnPropertyChanged([CallerMemberName] string name = "") =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
private void IconClicked()
{
this.IconAction?.Invoke();// invoke action
}
}
Best Regards,
Wenyan Zhang
If the answer is the right solution, please click "Accept Answer" and kindly upvote it. If you have extra questions about this answer, please click "Comment".
Note: Please follow the steps in our documentation to enable e-mail notifications if you want to receive the related email notification for this thread.