有什么办法可以从ViewModel更改菜单选择的项目吗?

时间:2019-07-02 11:00:54

标签: c# multithreading xamarin.forms menu-items

我正在尝试从Xamarin.Forms应用程序的ViewModel中更改菜单选择的项目。我该如何更改?

我已经将ListView SelectedItem属性绑定到ViewModel中的字段,且模式为“ TwoWay”。我也使用BeginInvokeOnMainThread和ContinueWith。 为了绑定事件,我创建了一个行为并将Command绑定到事件。 所有方式都不会改变所选项目。

<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();
                    });
            }));

我希望将所选项目从项目ID 2更改为ID 0,但是即使将SelectedItem变量更改为ID 0,它也始终停留在ID2。我的意思是视觉表示不会改变。

1 个答案:

答案 0 :(得分:0)

我编写了一个简单的演示来更新菜单选择项,您可以参考它。当我单击按钮时,无论单击哪个菜单项,selectedItem都将返回到第一个

enter image description here

有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

公共局部类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));
    }
}