【问题标题】:How To - Properly Bind Button Inside of ListView to View Model Property如何 - 将 ListView 内的按钮正确绑定到查看模型属性
【发布时间】:2019-08-08 03:17:29
【问题描述】:

我似乎在将命令连接到按钮时遇到问题。

假设我有以下内容:

MainPageViewModel.cs

public class MainPageViewModel : ViewModelBase
{
    private ICollection<MenuItem> _menuItems;

    public MainPageViewModel(INavigationService navigationService) : base(navigationService)
    {
        TestCommand = new DelegateCommand(TestCommandExecute);
        Title = "Menu";
    }

    public ICollection<MenuItem> MenuItems
    {
        get
        {
            return _menuItems;
        }

        private set
        {
            SetProperty(ref _menuItems, value, nameof(MenuItems));

            return;
        }
    }

    public DelegateCommand TestCommand
    {
        get;

        private set;
    }

    private void TestCommandExecute()
    {
        return;
    }
}

MainPage.xaml

<?xml version="1.0" encoding="utf-8" ?>

<ContentPage xmlns="http://xamarin.com/schemas/2014/forms" xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" x:Class="Menu.Views.MainPage" x:Name="Root" Title="{Binding Title}">
    <StackLayout>
        <Button Command="{Binding Mode=OneWay, Path=TestCommand}" Text="Test" />
        <ListView ItemsSource="{Binding Mode=OneWay, Path=MenuItems}" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <ViewCell.View>
                            <Button Command="{Binding Path=TestCommand, Source={x:Reference Name=Root}}" Text="{Binding Path=Title}" />
                        </ViewCell.View>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage>

当我单击“测试”按钮时该命令将触发,但当我单击通过 ListView 生成的任何按钮时它不会触发。我已经通过在TestCommandExecute 方法上放置一个断点来确认这一点。我没有看到任何错误正在生成。

这是将列表视图中的按钮连接到视图模型中的命令的正确方法吗?

【问题讨论】:

  • 列表中的那些东西也应该是视图模型......带有自己的命令,可能......
  • @Haukinger - 为什么列表中的东西本身需要是视图模型?无论如何,我不想绑定到列表项上的命令。相反,我试图绑定到页面视图模型上的命令。每个按钮将触发相同的命令,相应的操作将由命令参数驱动。
  • @Haukinger 这是一个糟糕的建议,而且 100% 错误!您不应该仅仅为了绑定到 ListView 而创建 ViewModel。
  • @DanS。那么 XF 与 WPF 的区别确实比我想象的要大得多——我一直在坚持“不直接绑定到模型”方面有积极的经验。
  • @Haukinger 并不是说​​ XF 与 WPF 不同,您通过将所有内容包装在它自己的 ViewModel 中的建议错过了 MVVM 的整个概念。您应该让您的模型实现 INotifyPropertyChanged 但这不会使它们成为 ViewModel,也不应该让 ViewModel 尝试像您所建议的那样拥有 ViewModel 列表。这只是糟糕的设计。

标签: xamarin.forms prism


【解决方案1】:

我通过另一个 Stack Overflow 问题解决了这个问题...

绑定应该是...

<Button Command="{Binding Path=BindingContext.TestCommand, Source={x:Reference Name=Root}}" Text="{Binding Path=Title}" />

...而不是...

<Button Command="{Binding Path=TestCommand, Source={x:Reference Name=Root}}" Text="{Binding Path=Title}" />

注意添加的 BindingContext。

【讨论】:

  • 虽然技术上是正确的,但值得指出的是这过于冗长。您不需要指定 Binding 的 Path 属性,也不需要指定 Reference 的 Name 属性。它应该看起来更像{Binding BindingContext.TestCommand, Source={x:Reference Root}}
【解决方案2】:

试试这个:

<Button Command="{Binding DataContext.TestCommand, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type local:MainPage}}}"/>

【讨论】:

  • 应该是{Binding DataContext.TestCommand, Source={RelativeSource FindAncestor, AncestorType={x:Type local:MainPage}}},否则很好的解决方案!
猜你喜欢
  • 2017-06-22
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2018-05-25
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多