C# 从视图模型绑定到ListView项属性
我正在尝试使用itemtapped属性将事件绑定到菜单页上的ListView。目前我正在我的应用程序中使用MVVM(Xamarin form labs)框架。我试图做到的是,当用户点击菜单项时,应用程序将导航到正确的视图 以下是xaml代码:C# 从视图模型绑定到ListView项属性,c#,xaml,mvvm,xamarin,xamarin.forms,C#,Xaml,Mvvm,Xamarin,Xamarin.forms,我正在尝试使用itemtapped属性将事件绑定到菜单页上的ListView。目前我正在我的应用程序中使用MVVM(Xamarin form labs)框架。我试图做到的是,当用户点击菜单项时,应用程序将导航到正确的视图 以下是xaml代码: <ListView x:Name="list" ItemsSource="{Binding MenuItems}" SelectedItem="{Binding SelectedItem}" Ite
<ListView x:Name="list"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem}"
ItemTapped= SET-BINDING-HERE >
<ListView.ItemTemplate>
<DataTemplate>
<ViewCell>
<ViewCell.View>
//setup template here
</ViewCell.View>
</ViewCell>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
如果我将函数添加到视图的代码中,然后设置itemstapped='navigato,我目前可以实现这一点,但这似乎是错误的,因为它破坏了MVVM的概念。我真正想做的是将事件绑定到我的ViewModel中的相同功能,如下所示:
<ListView x:Name="list"
ItemsSource="{Binding MenuItems}"
SelectedItem="{Binding SelectedItem}"
ItemTapped= "{Binding NavigateTo}" > // this binding is to the ViewModel
//此绑定是到ViewModel的
但是,这不起作用,或者我做得不对。当我尝试以这种方式实现它时,代码会产生错误
错误:
Xamarin.Forms.Xaml.XamlParseException:在Xamarin.Forms.Xaml.BaseValueNode.SetPropertyValue中找不到name ItemTapped的属性我遵循相同的体系结构,通过创建自定义列表控件创建了1个bindable属性,我使用以下代码在视图模型中覆盖了该属性: 我的PCL中的自定义控件[.cs]页
using System;
using System.Windows.Input;
using Xamarin.Forms;
namespace YourNS {
public class ListView : Xamarin.Forms.ListView {
public static BindableProperty ItemClickCommandProperty = BindableProperty.Create<ListView, ICommand>(x => x.ItemClickCommand, null);
public ListView() {
this.ItemTapped += this.OnItemTapped;
}
public ICommand ItemClickCommand {
get { return (ICommand)this.GetValue(ItemClickCommandProperty); }
set { this.SetValue(ItemClickCommandProperty, value); }
}
private void OnItemTapped(object sender, ItemTappedEventArgs e) {
if (e.Item != null && this.ItemClickCommand != null && this.ItemClickCommand.CanExecute(e)) {
this.ItemClickCommand.Execute(e.Item);
this.SelectedItem = null;
}
}
}
}
使用系统;
使用System.Windows.Input;
使用Xamarin.Forms;
名称空间YourNS{
公共类ListView:Xamarin.Forms.ListView{
公共静态BindableProperty ItemClickCommandProperty=BindableProperty.Create(x=>x.ItemClickCommand,null);
公共列表视图(){
this.ItemTapped+=this.OnItemTapped;
}
公共ICommand ItemClickCommand{
获取{return(ICommand)this.GetValue(ItemClickCommandProperty);}
设置{this.SetValue(ItemClickCommandProperty,value);}
}
已映射的私有void(对象发送方,ItemTappedEventArgs e){
如果(e.Item!=null&&this.ItemClickCommand!=null&&this.ItemClickCommand.CanExecute(e)){
这个.ItemClickCommand.Execute(即Item);
this.SelectedItem=null;
}
}
}
}
我的XAML页面
<ContentPage ...
xmlns:local="clr-namespace:Samples.Views;assembly=Your Assebly Name">
<local:ListView ItemClickCommand="{Binding Select}"
ItemsSource="{Binding List}">
在我的视图模型中[在本例中,我只打开了dialog action sheet]
private Command<Signature> selectCmd;
public Command<Signature> Select {
get {
this.selectCmd = this.selectCmd ?? new Command<Signature>(s =>
this.dialogs.ActionSheet(new ActionSheetConfig()
.Add("View", () => {
if (!this.fileViewer.Open(s.FilePath))
this.dialogs.Alert(String.Format("Could not open file {0}", s.FileName));
})
.Add("Cancel")
)
);
return this.selectCmd;
}
}
private命令selectCmd;
公共命令选择{
得到{
this.selectCmd=this.selectCmd??新命令(s=>
this.dialogs.ActionSheet(新的ActionSheetConfig()
.Add(“视图”,()=>{
如果(!this.fileViewer.Open(s.FilePath))
this.dialogs.Alert(String.Format(“无法打开文件{0}”,s.FileName));
})
.添加(“取消”)
)
);
返回this.selectCmd;
}
}
或者,您可以使用附加的行为
public static class ListViewAttachedBehavior
{
public static readonly BindableProperty CommandProperty =
BindableProperty.CreateAttached (
"Command",
typeof(ICommand),
typeof(ListViewAttachedBehavior),
null,
propertyChanged:OnCommandChanged);
static void OnCommandChanged (BindableObject view, object oldValue, object newValue)
{
var entry = view as ListView;
if (entry == null)
return;
entry.ItemTapped += (sender, e) =>
{
var command = (newValue as ICommand);
if(command == null)
return;
if(command.CanExecute(e.Item))
{
command.Execute(e.Item);
}
};
}
}
然后在ListView中调用它
<ListView
RowHeight="70"
x:Name="AcquaintanceListView"
b:ListViewAttachedBehavior.Command="{Binding ItemSelectedCommand}"
ItemsSource="{Binding Acquaintances}">
我认为这是一个比目前更好的解决方案,并且正在考虑开发类似的解决方案(尝试限制代码共享的数量或渲染)。我还有一个问题,添加命令参数是否与添加项目单击命令相同?我希望能够将单击的项目传递到下一个视图。很抱歉,我知道这是一个旧问题,但我遇到以下错误:“Xamarin.Forms.ListView”不包含“ItemClickCommand”的定义,并且没有扩展方法”无法找到ItemClickCommand“接受类型为”Xamarin.Forms.ListView“的第一个参数(是否缺少using指令或程序集引用?),你知道为什么吗?我已经添加了所有相关的引用,但intellisense没有显示ItemClickCommand。谢谢。@Thierry:你在使用或吗?ItemClickCommand没有在Xamarin.Forms附带的内置ListView上定义。这里的答案继承了ListView,用名为Item的新属性创建了自己的自定义ListViewClickCommand。要使用它,您需要将正确的xmlns定义添加到XAML的顶部,并使用or,其中[which]是您定义的xmlns。在PCL上对我来说效果很好。别忘了CachingStrategy支持。填充CachingStrategy属性后,您需要实现额外的构造函数以防止“..找不到ctor.”Xamarin异常。将以下构造函数添加到自定义ListView代码。public ListViewWithCommands(ListViewCachingStrategy cachingStrategy):base(cachingStrategy){ItemTapped+=ListViewWithCommands_ItemTapped;}