0

I'm trying to change menu selected item from my ViewModel in my Xamarin.Forms application. How can I change that?

I've bind ListView SelectedItem property to field in my ViewModel, with mode "TwoWay". Also I used BeginInvokeOnMainThread and ContinueWith. To bind an event I created a behavior and bind Command to event. All the ways didn't change selected item.

<ListView
            x:Name="ListViewMenu"
            HasUnevenRows="True"
            ItemsSource="{Binding menuItems}"
            SelectedItem="{Binding SelectedItem, Mode=TwoWay}">
<ListView.Behaviors>
                <behaviors:EventToCommandBehavior
                    Command="{Binding command}"
                    Converter="{StaticResource SelectedItemConverter}"
                    EventName="ItemSelected" />
            </ListView.Behaviors>
private HomeMenuItem selectedItem { get; set; }
        public HomeMenuItem SelectedItem
        {
            get { return selectedItem; }
            set
            {
                selectedItem = value;
                this.OnPropertyChanged();
            }
        }
command = new AsyncRelayCommand((sender) => this.ItemSelected(sender).ContinueWith((arg) =>
            {
                HomeMenuItem menuItem = sender as HomeMenuItem;

                if(menuItem.Id != SelectedItem.Id)
                    Device.BeginInvokeOnMainThread(() =>
                    {
                        SelectedItem = menuItems.Where(s => s.Id.Equals(menuItem.Id)).FirstOrDefault();
                    });
            }));

I expected to change selected item, from item Id 2 to Id 0 but this always stay on Id 2, even if SelectedItem variable is changed to Id 0. I mean visual representation don't change.

Brath
  • 53
  • 1
  • 5

1 Answers1

0

I wrote a simple demo to update the menu selected item, you could refer to it.When I click the button the listview selectedItem will reback to the first one whatever I click the which one

enter image description here

There is MainPage.xml

   <StackLayout>
    <Button Command="{Binding UpdateCommand}"></Button>
    <ListView
        x:Name="ListViewMenu"
        HasUnevenRows="True"
        ItemsSource="{Binding menuItems}"
        SelectedItem="{Binding SelectedItem, Mode=TwoWay}">

        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout>
                        <Label Text="{Binding Name}" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>   
    </ListView>
</StackLayout>

MainPage.xml.cs

public partial class MainPage : ContentPage {

    public MainPageModelView model { get; set; }
    public MainPage()
    {
        InitializeComponent();



        model = new MainPageModelView();
        BindingContext = model;
    }


}

MainPageModelView.cs

public class MainPageModelView: INotifyPropertyChanged
{
    public ObservableCollection<HomeMenuItem> menuItems { set; get; }
    public event PropertyChangedEventHandler PropertyChanged;

    public MainPageModelView()
    {
        menuItems = new ObservableCollection<HomeMenuItem>();
        menuItems.Add(new HomeMenuItem() { Name = "Mr. Mono1", Id = 1 });
        menuItems.Add(new HomeMenuItem() { Name = "Mr. Mono2", Id = 2 });
        menuItems.Add(new HomeMenuItem() { Name = "Mr. Mono3", Id = 3 });
        menuItems.Add(new HomeMenuItem() { Name = "Mr. Mono4", Id = 4 });
    }

    private HomeMenuItem selectedItem { get; set; }
    public HomeMenuItem SelectedItem
    {
        get { return selectedItem; }
        set
        {
            selectedItem = value;
            this.OnPropertyChanged();
        }
    }


    Command _updateCommand;

    public Command UpdateCommand
    {
        get
        {
            return _updateCommand ?? (_updateCommand = new Command(ExecuteSaveCommand));
        }
    }
    void ExecuteSaveCommand()
    {
        Device.BeginInvokeOnMainThread(() =>
        {
               SelectedItem = menuItems[0];
        });
        //SelectedItem = menuItems.Where(s => s.Id.Equals(menuItem.Id)).FirstOrDefault();

    }
    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this,
        new PropertyChangedEventArgs(propertyName));
    }
}
Leon
  • 8,404
  • 2
  • 9
  • 52
  • @Brath Are there any updates for this issue? If the reply is helpful, please try to mark it as an answer, it will help others who have similar issue. – Leon Jul 03 '19 at 15:04