【问题标题】:Xamarin command is not working for object of ObservablecollectionXamarin 命令不适用于 Observablecollection 的对象
【发布时间】:2018-02-20 13:48:13
【问题描述】:

我是 Xamarin 的新手,目前正在研究我面临以下问题的解决方案。 我有一个 A 类,它是我的模型类,B 类是我的 viewModel。 模型类

Class A  : INotifyPropertyChanged
{
   public string sampleprop { get; set; }
   public event PropertyChangedEventHandler PropertyChanged;
   public virtual void OnPropertyChanged(string propertyName)
        {
            if (PropertyChanged == null)
                return;
        PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
        }
}

我正在将 A 类的对象创建为 B 类中的可观察集合。

Class B
    {
   public Command<string> CallCommand { get; set; }
   public ObservableCollection<A>   AobjectsCollection { get; set; }

   public B()
        {
            AobjectsCollection = new ObservableCollection<A>();
            CallCommand = new Command<string>((string arg) => 
    DoMakeCall(arg));
        }
    public void DoMakeCall(string phNumber)
        {
            string s = phNumber;
        }
}

将 B 类指定为我的主视图页面的绑定上下文。

public partial class Mainview : ContentPage
 {
    InitializeComponent ();
         BindingContext = new B();
  }

在主视图(xaml)中,我正在使用 ClassB 的可观察集合属性创建一个列表视图。

     <ListView x:Name="MessagesListView" 
                 ItemsSource="{Binding AobjectsCollection }"
                 HasUnevenRows="True" >
                 <ListView.ItemTemplate>
                   <DataTemplate>
                     <ViewCell >
                         <ViewCell.View>
             <Button x:Name="btnClick" Text="ClickMe" 
                    Command="{Binding CallCommand}" 
                    CommandParameter="sampleprop"/> 
             </ViewCell.View>
                         </ViewCell>
                   </DataTemplate>
                 </ListView.ItemTemplate>
      </ListView>

现在单击主页中的按钮(btnClick)不会调用我的viewModel的命令并执行我的方法DoMakeCall(string s)。

谁能帮我理解这段代码有什么问题?以及如何实现这种情况?

我的 Command 属性属于 VM 类,而不是 Model 类。我唯一需要知道的是如何正确设置上下文以使其工作。我不想使用中继命令。

【问题讨论】:

标签: xaml xamarin xamarin.forms


【解决方案1】:

建议您使用ItemSelected="Handle_ItemSelected,而不是使用按钮。

<ListView x:Name="MessagesListView" 
          ItemsSource="{Binding AobjectsCollection }"
          HasUnevenRows="True" 
          ItemSelected="Handle_ItemSelected">

您可以参考这里:Tap Gesture on List View Items

解释很详细。希望对您有所帮助。

【讨论】:

    【解决方案2】:

    您当前正在将每个 ViewCell 绑定到您的 A 模型。它没有对 B ViewModel 的引用(这是您要调用的命令所在的位置。要解决此问题,您需要告诉 ViewCell 按钮在 MessagesListView 的 BindingContext 上查找命令(在这种情况下是您的 B ViewModel)。看起来像这样:

    BindingContext="{Binding Source={x:Reference MessagesListView}, Path=BindingContext}"
    

    在完整的上下文中:

     <ListView x:Name="MessagesListView" 
               ItemsSource="{Binding AobjectsCollection }"
               HasUnevenRows="True" >
               <ListView.ItemTemplate>
                   <DataTemplate>
                       <ViewCell x:Name="viewCell">
                           <ViewCell.View>
                               <Button x:Name="btnClick" Text="ClickMe"
                                     BindingContext="{Binding Source={x:Reference MessagesListView}, Path=BindingContext}" 
                                     Command="{Binding CallCommand}" 
                                     CommandParameter="{Binding Source={x:Reference viewCell}, Path=BindingContext}"/> 
                           </ViewCell.View>
                       </ViewCell>
                   </DataTemplate>
               </ListView.ItemTemplate>
    </ListView>
    

    【讨论】:

    • 非常感谢,它适用于这种情况。但是当我在 classB 中有 List 而不是 Sampleprop 时,如何将当前对象(someotherclassobject)设置为 commandParameter?当我们将按钮的 Bindingcontext 设置为 ModelView 时,我无法获取填充列表视图的当前对象。我尝试过使用 CommandParameter ={Bindig .},但它没有用。 :(你能帮我吗?
    • 我添加了一些代码来使命令参数绑定到单元格的原始视图模型,我认为这将是您的 ClassA 实例。然后,您的命令将接受绑定到您单击的 ViewCell 的 ClassA 实例。
    • 感谢您的回复。绑定 ViewCell 不起作用,它会引发运行时异常。我尝试过使用 ViewCell 和 ViewCell.BindingContext... 但没有运气:'(
    • @Will Decker。最后它使用下面的代码
    • 您的解决方案帮助我解决了我的按钮命令(按钮位于 ListView 的 DataTemplate 中)无法触发的类似问题。谢谢! :)
    猜你喜欢
    • 2013-05-26
    • 2021-06-17
    • 2011-03-28
    • 1970-01-01
    • 2016-07-17
    • 1970-01-01
    • 1970-01-01
    • 2017-07-13
    • 2013-07-09
    相关资源
    最近更新 更多