Xamarin MVVM,将ListView项绑定为命令参数



我有一个从视图模型填充的ListView,现在我可以轻松地将数据模板的元素绑定到数据源项的属性,并将这些属性发送到视图模型中的命令。然而,我认为应该能够发送整个源项目。然而,当我发送字符串以外的任何内容时,要么应用程序崩溃,要么按钮都被禁用,似乎不会触发命令。这个OOP和xamarin新手将非常感谢任何提示/帮助。我怀疑这只是按钮中的语法,或者命令中我不理解的语法,我现在拥有的是:

<ContentPage.BindingContext>
<local:TestViewModel/>
</ContentPage.BindingContext>
<ContentPage.Content>
<StackLayout  >
<Label Text="{Binding SelectedItem.Term_id}"
VerticalOptions="CenterAndExpand" 
HorizontalOptions="CenterAndExpand" />
<BoxView HeightRequest="1" BackgroundColor="Black" HorizontalOptions="FillAndExpand" />
<ListView x:Name="propListView"
SelectedItem="{Binding SelectedItem}"
ItemsSource="{Binding SimpleProperties}"  >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell x:Name="theItem" >
<StackLayout Orientation="Horizontal">
<Button Text="{Binding Agt_name}"
Command="{Binding BindingContext.doCheckin, Source={x:Reference Page}}"
CommandParameter="{Binding BindingContext.doCheckin, Source={x:Reference theItem}, Mode=OneWayToSource}"
/>
<Label Text="{Binding MilesDistance, StringFormat='~{0:f2} mi.'},
Converter={ConvertToDouble}}" HorizontalOptions="CenterAndExpand" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</StackLayout>
</ContentPage.Content>

using AgentApp.Models;
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Input;
using Xamarin.Forms;
namespace AgentApp
{
class TestViewModel : BaseViewModel
{
private ObservableCollection<Property> simpleProperties;
public ObservableCollection<Property> SimpleProperties { set { SetProperty(ref simpleProperties, value); } get { return simpleProperties; } }
private Property selectedItem;
public Property SelectedItem { get { return selectedItem; } set { SetProperty(ref selectedItem, value); } }
public ICommand setSelection { private set; get; }
public ICommand doCheckin { private set; get; }
public TestViewModel()
{
var SimplePropertiesList = new List<Property>();
for (int i = 1; i <= 5; i++)
{
Property prop = new Property();
prop.Term_id = i.ToString();
prop.Agt_name = "Prop " + i.ToString();
prop.MilesDistance = (double)i * 2.5;
SimplePropertiesList.Add(prop);
}
SimpleProperties = new ObservableCollection<Property>(SimplePropertiesList);
/* for buttons:*/
doCheckin = new Command<Property>(
execute: (Property item) =>
{
Console.WriteLine("doCheckin() executes: " + item.Term_id);
SelectedItem = item;
},
canExecute: (Property item) =>
{
Console.WriteLine("doCheckin() canExecute return" + item.Term_id);
return (SelectedItem != item); 
}
);
}
}
}

当然还有

class BaseViewModel : INotifyPropertyChanged
{
public bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
{
if (Object.Equals(storage, value)) return false;
storage = value;
OnPropertyChanged(propertyName);
return true;
}
public virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
public event PropertyChangedEventHandler PropertyChanged;
}

提前感谢!

然而,我认为应该能够发送整个源项。然而,当我发送字符串以外的任何内容时,要么应用程序崩溃,要么按钮都被禁用,似乎不会触发命令。

根据您的描述,您想在单击按钮时传递当前项目,对吗?如果是,正如Jason所说,修改按钮命令参数如下:

<ListView
x:Name="propListView"
ItemsSource="{Binding SimpleProperties}"
SelectedItem="{Binding selectedItem}">
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<StackLayout Orientation="Horizontal">
<Button
Command="{Binding BindingContext.doCheckin, Source={x:Reference page27}}"
CommandParameter="{Binding .}"
Text="{Binding Agt_name}" />
<Label HorizontalOptions="CenterAndExpand" Text="{Binding MilesDistance}" />
</StackLayout>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
doCheckin = new Command((e) =>
{
var item = (e as Property);
Console.WriteLine("the property Term_id is {0} ", item.Term_id);
});

顺便说一句,selecteditem需要实现INotifyPropertychanged来更新数据。

private Property _selectedItem;
public Property selectedItem 
{ 
get { 
return _selectedItem; 
} 
set { 
_selectedItem=value;
OnPropertyChanged("selectedItem");
} 
}      

最新更新