首页 > 解决方案 > 向动态填充的 ListView 中的元素添加不同的命令

问题描述

我有一个动态添加项目的 ListView。列表中的每一行都包含一个标签、一个开关和一个按钮。只有在切换该 ViewCell 的 Switch 时,相应的 Button 才应该可见。相应的 Button 还应该有一个特定于列表中该项目的命令。我怎样才能做到这一点?我正在使用 MVVM 模式。

<ListView HorizontalOptions="FillAndExpand" ItemsSource="{Binding SomeList}">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout HorizontalOptions="FillAndExpand" Orientation="Horizontal">
                    <Label
                            HorizontalOptions="StartAndExpand"
                            Text="{Binding SomePropertyFromSomeList}"
                            VerticalOptions="Center" />
                    <Switch />
                    <Button
                            Command="{Binding DoSomethingSpecificToThisSwitch}"
                            IsVisible="{Binding VisibleWhenThisSwitchIsToggled}"
                            Text="{Binding AlsoDependentOnWhichSwitch}" />
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

标签: c#xamlxamarin.forms

解决方案


我发现解决这个问题的最佳方法是使用 a并根据数据的上下文CommandParameter决定在你的情况下做什么。ViewModelViewCell

如果您使用 Binding,您可以通过选择 绑定到当前数据的整个上下文。( dot ),这样当前 ViewCell 中的数据就会传递给您的 ViewModel。

让我们看看你是如何编码的……你的视图应该是这样的

<?xml version="1.0" encoding="utf-8"?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:local="clr-namespace:TestCommand"
             x:Name="TestPage"
             x:Class="TestCommand.MainPage">
    <StackLayout>
        <ListView ItemsSource="{Binding Persons}" RowHeight="50">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout>
                            <Label Text="{Binding Name}" />
                            <Button Text="Click" Command="{Binding DoCommand, Source={x:Reference TestPage}}" CommandParameter="{Binding .}" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

请注意,您需要为页面提供名称!这样您就可以在每个 ViewCell 中指向相同的命令。但是使用命令参数传入当前的 ViewCell 数据。

在您的 ViewModel 中,您可以对“选定”数据采取行动......并执行以下特定操作:

public List<Person> Persons { get; set; } = new List<Person>() { new Person() { Name = "Glenn Versweyveld" }, new Person() { Name = "John Do" } };

private Command<Person> _doCommand;
public Command<Person> DoCommand => _doCommand ?? (_doCommand = new Command<Person>((Person obj) => HandlePerson(obj)));

private void HandlePerson(Person obj)
{

}

推荐阅读