【问题标题】:How can I convert this into a Command for the ViewModel?如何将其转换为 ViewModel 的命令?
【发布时间】:2021-05-24 05:37:27
【问题描述】:

我知道如何绑定事件,但我无法通过虚拟机进行热锻炼:

void TapGestureRecognizer_ElderList_Single(System.Object sender, System.EventArgs e)
{
    var stacklayout = sender as StackLayout;
    ListElders.SelectedItem = stacklayout.BindingContext;
    ListElders.Focus();
}

我的理解是View知道ViewModel,而ViewModel不知道View。这向我表明,在这种情况下,在 Code Behind 中使用 Tapped 事件实际上是正确的例程。

是吗?不能从 ViewModel 中完成吗?


我想做什么?

如果我点击列表视图的左侧或右侧(在列表本身之外),则它会正确选择并显示为蓝色。这按预期工作。

但是,如果我单击列表中的项目本身,则默认情况下不会选择任何内容。所以我们从这个开始:

void TapGestureRecognizer_ElderList_Single(System.Object sender, System.EventArgs e)
{
    var stacklayout = sender as StackLayout;
    ListElders.SelectedItem = stacklayout.BindingContext;
    //ListElders.Focus();
}

现在,当您选择或单击项目本身时,它会被选中。但是当我的窗口上有两个列表视图时,我发现选择并不总是显示为蓝色。它有时显示为深灰色。我认为这是因为列表视图没有焦点。

当我添加焦点调用时,它将始终显示蓝色。


目前已完成 XAMl:

  <ListView
        x:Name="ListElders"
        HasUnevenRows="True"
        HorizontalOptions="StartAndExpand"
        ItemsSource="{Binding EldersCollection}"
        SelectedItem="{Binding SelectedElder, Mode=TwoWay}"
        VerticalOptions="StartAndExpand">
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <StackLayout Padding="2">
                        <Label
                            FontSize="Small"
                            Text="{Binding .}"
                            VerticalTextAlignment="Center" />
                        <StackLayout.GestureRecognizers>
                            <TapGestureRecognizer NumberOfTapsRequired="1" Tapped="TapGestureRecognizer_ElderList_Single" />
                            <TapGestureRecognizer
                                Command="{Binding Path=BindingContext.EditElderCommand, Source={Reference ListElders}}"
                                CommandParameter="{Binding Path=SelectedItem, Source={Reference ListElders}}"
                                NumberOfTapsRequired="2" />
                        </StackLayout.GestureRecognizers>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>

【问题讨论】:

  • TapGestureRecognizers 有一个专门针对这种情况的 Command 属性
  • @Jason 那么我哪里出错了? SelectedElder 映射到 Selected 项,而我们在 ViewModel 中没有 ListView 项,所以无法调用 Focus。
  • 这里没有多少上下文让我了解您要完成的工作或您面临的具体问题。如果您问“如何从 VM 操作 UI 对象?”那么将其作为 View 中的事件处理可能更有意义,而不是 VM。

标签: c# xaml xamarin.forms command


【解决方案1】:

您可以将 ListView 作为 CommandParameter 传递给您的视图模型中的 Command。

类似:

<StackLayout.GestureRecognizers>
    <TapGestureRecognizer
        Command="{Binding TapCommand}"
        CommandParameter="{x:Reference ListElders}" />
</StackLayout.GestureRecognizers>

<ListView x:Name = "ListElders">
  ....
</ListView>

在您的视图模型中:

ICommand  TapCommand = new Command<ListView>(TapEvent);

 private void TapEvent(ListView lv)
   {
        //you could get the listview here
   }

更新(如果您只想突出显示所选项目)。

<ListView
    x:Name="ListElders"
    HasUnevenRows="True"
    HorizontalOptions="StartAndExpand"
    ItemsSource="{Binding EldersCollection}"
    ItemSelected="ListElders_ItemSelected"
    SelectedItem="{Binding SelectedElder, Mode=TwoWay}"
    VerticalOptions="StartAndExpand">
    <ListView.ItemTemplate>
        <DataTemplate>
            <ViewCell>
                <StackLayout Padding="2">
                    <Label
                        FontSize="Small"
                        Text="{Binding .}"
                        VerticalTextAlignment="Center" />                    
                </StackLayout>
            </ViewCell>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

在 page.cs 中:

private void ListElders_ItemSelected(object sender, SelectedItemChangedEventArgs e)
    {
        //do something you want when you select item/
    }

【讨论】:

  • 感谢您的回答。我可以看到这将如何链接到后面的代码。我的直觉是,这纯粹是 UI 逻辑。我真的不想对模型本身做任何事情。我只希望列表视图选定的项目在单击时保持蓝色。请参阅我更新的问题。此外,我仍然不知道如何在命令版本中复制 Tap 处理程序的内容(它的发送者是堆栈面板)。我会的,我会将它们作为事件留在代码中。
  • @AndrewTruckle 我认为这可能是因为您将 TapGestureRecognizer 添加到 StackLayout 以与 ListView ItemSelected 事件发生冲突。为什么不直接使用 ListView ItemSelected 事件呢?
  • 我用完整的 XAML 为列表视图元素更新了我的问题,以便您查看我是否可以按照您的建议进行操作。听起来你是对的。
  • @AndrewTruckle 如果我理解正确,您只想在选择项目时突出显示它,对吗?如果是,您不需要像上面的更新一样添加TapGestureRecognizer。跨度>
  • 谢谢。当他们只是选择一个项目时,我不想“做”任何事情。但它应该这样做——“选择”它们。那是错。如果他们双击,我确实想做的是调用我的编辑命令。没事儿。我会调查你提供的内容。
猜你喜欢
  • 1970-01-01
  • 2018-04-02
  • 2021-10-08
  • 2020-02-10
  • 1970-01-01
  • 2020-11-25
  • 2017-10-19
  • 2016-10-24
  • 2020-10-21
相关资源
最近更新 更多