Warning: file_get_contents(/data/phpspider/zhask/data//catemap/2/csharp/333.json): failed to open stream: No such file or directory in /data/phpspider/zhask/libs/function.php on line 167

Warning: Invalid argument supplied for foreach() in /data/phpspider/zhask/libs/tag.function.php on line 1116

Notice: Undefined index: in /data/phpspider/zhask/libs/function.php on line 180

Warning: array_chunk() expects parameter 1 to be array, null given in /data/phpspider/zhask/libs/function.php on line 181
C# 从视图模型绑定到ListView项属性_C#_Xaml_Mvvm_Xamarin_Xamarin.forms - Fatal编程技术网

C# 从视图模型绑定到ListView项属性

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

我正在尝试使用itemtapped属性将事件绑定到菜单页上的ListView。目前我正在我的应用程序中使用MVVM(Xamarin form labs)框架。我试图做到的是,当用户点击菜单项时,应用程序将导航到正确的视图

以下是xaml代码:

<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;}