C# 如何在xamarin.forms中的viewcell中设置按钮以从内容页viewmodel调用命令?

C# 如何在xamarin.forms中的viewcell中设置按钮以从内容页viewmodel调用命令?,c#,mvvm,xamarin.forms,binding,C#,Mvvm,Xamarin.forms,Binding,在GroceryListViewModel中,有一个名为ButtonClicked的命令,我希望使用一个按钮。但是,该按钮位于ListView的ViewCell中,无法访问该命令。我当前所做的操作会导致每次加载ViewCell以及单击ViewCell时调用该命令。该按钮不适用于列表顶部的一些ViewCell,但适用于列表的下一部分 <?xml version="1.0" encoding="utf-8" ?> <ContentPage x

在GroceryListViewModel中,有一个名为ButtonClicked的命令,我希望使用一个按钮。但是,该按钮位于ListView的ViewCell中,无法访问该命令。我当前所做的操作会导致每次加载ViewCell以及单击ViewCell时调用该命令。该按钮不适用于列表顶部的一些ViewCell,但适用于列表的下一部分

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:d="http://xamarin.com/schemas/2014/forms/design"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
             xmlns:VM="clr-namespace:FoodLifeApp.ViewModels"
             mc:Ignorable="d"
             x:Class="FoodLifeApp.PageViews.GroceryListPage"
             x:Name="GroceryList">
    <ContentPage.BindingContext >
        <VM:GroceryListViewModel x:Name="VMGroceryList"/>
    </ContentPage.BindingContext>
    <ListView x:Name="MyListView"
            ItemsSource="{Binding DisplayList}"
            IsGroupingEnabled="True"
            HasUnevenRows="True"
            CachingStrategy="RecycleElement">
        <ListView.Header >
            <SearchBar Placeholder="Search" 
                       Text="{Binding SearchText}" 
                       HeightRequest="40" 
                       SearchCommand="{Binding Search}"
                       />
        </ListView.Header>
        <ListView.GroupHeaderTemplate >
            <DataTemplate>
                <ViewCell Height="20">
                    <Label Text="{Binding Heading}"  
                           BackgroundColor="LightGray" 
                           FontAttributes="Bold" 
                           HorizontalTextAlignment="Center" 
                           VerticalTextAlignment="Center" />
                </ViewCell>
            </DataTemplate>
        </ListView.GroupHeaderTemplate>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell Height="40">
                    <StackLayout Orientation="Horizontal" >
                        <Label Text="{Binding ProductName}" 
                               VerticalTextAlignment="Center"/>
                        <Label Text="{Binding ProductSize}" 
                               FontSize="10" 
                               VerticalTextAlignment="Center"/>
                        <Button ImageSource="{Binding ButtonImage}" 
                                     BackgroundColor="Transparent"
                                     CommandParameter="{Binding ProductName}" 
                                     Command="{Binding Path=ButtonClicked, Source={x:Reference VMGroceryList}}" />
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
    </ListView>
</ContentPage>

class GroceryListViewModel:ContentPage,INotifyPropertyChanged
{
私有列表(shoppinglist的列表);;
私人列表搜索结果;
私有字符串_searchText;
专用命令搜索命令;
公共事件属性更改事件处理程序属性更改;
公共杂货店列表视图模型()
{
var meatList=new ShoppingList()
{
new ShoppingItem(){ProductName=“Beef”,ProductQuantity=7},
新建ShoppingItem(){ProductName=“Chicken”,ProductQuantity=3},
new ShoppingItem(){ProductName=“Pork”,ProductQuantity=5},
};
肉类列表。标题=“肉类”;
var fruitList=new ShoppingList()
{
new ShoppingItem(){ProductName=“Apple”,ProductQuantity=12},
新建ShoppingItem(){ProductName=“Bananas”,ProductQuantity=6},
new ShoppingItem(){ProductName=“Peaches”,ProductQuantity=4},
};
水果列表。标题=“水果”;
var vegetableList=new ShoppingList()
{
new ShoppingItem(){ProductName=“Corn”,ProductQuantity=8},
new ShoppingItem(){ProductName=“土豆”,ProductQuantity=9},
new ShoppingItem(){ProductName=“绿豆”,ProductQuantity=8},
新建ShoppingItem(){ProductName=“Brocoli”,ProductQuantity=1}
};
vegetableList.Heading=“蔬菜”;
DisplayList=新列表()
{
肉类列表,
水果列表,
蔬菜名录
};
搜索=新命令(异步()=>
{
ShoppingList tempList=新建ShoppingList();
templast.Heading=“搜索结果”;
RestHelper restH=新的RestHelper();
JObject sRes=await restH.GetKroger(SearchText);
foreach(sRes[“数据”]中的var currItem)
{
添加(新ShoppingItem(){ProductName=currItem[“description”].ToString(),ProductQuantity=0,ProductSize=currItem[“items”][0][“size”].ToString());
}
DisplayList=新列表(){templalist};
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(“显示列表”);
});
}
公共列表显示列表
{
得到
{
if(IsSearchingBool.IsSearchingInstance.getIsSearching())
{
WriteLine(“返回搜索结果”);
返回搜索结果;
}否则
{
Debug.WriteLine(“返回杂货清单”);
返回\u shoppinglist的列表;
}
}
设置
{
if(IsSearchingBool.IsSearchingInstance.getIsSearching())
{
_搜索结果=值;
}否则
{
_ListOfShoppingList=值;
}
base.OnPropertyChanged();
}
}
公共字符串搜索文本
{
设置
{
if(value.Length==0&&IsSearchingBool.IsSearchingInstance.getIsSearching()==true)
{
IsSearchingBool.IsSearchingInstance.setIsSearching(false);
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(“显示列表”);
}else if(value.Length>0&&IsSearchingBool.IsSearchingInstance.getIsSearching()==false)
{
IsSearchingBool.IsSearchingInstance.setIsSearching(真);
Search.CanExecute(这个);
}
_搜索文本=值;
base.OnPropertyChanged();
}
得到
{
返回搜索文本;
}
}
公共ICommand搜索
{
获得;私人设置;
}
公共ICommand按钮已单击
{
得到
{
Debug.WriteLine(“在按钮中单击”);
if(IsSearchingBool.IsSearchingInstance.getIsSearching())
{
Debug.WriteLine(“正在搜索”);
返回新命令((itemName)=>{
Debug.WriteLine(itemName);
Debug.WriteLine(_SearchResults[0].ToString());
Debug.WriteLine(_ListOfShoppingList[0].ToString());
ShoppingItem temp=\u SearchResults[0]。查找(x=>x.ProductName.Equals(itemName));
_搜索结果[0]。删除(临时);
_ListOfShoppingList[0]。添加(临时);
PropertyChanged?.Invoke(这是新的PropertyChangedEventArgs(“显示列表”);
});
}否则
{
Debug.WriteLine(“不搜索”);
返回东北
class GroceryListViewModel : ContentPage, INotifyPropertyChanged
    {
        private List<ShoppingList> _ListOfShoppingList;
        private List<ShoppingList> _SearchResults;
        private String _searchText;
        private Command searchCommand;
        public event PropertyChangedEventHandler PropertyChanged;

        public GroceryListViewModel()
        {
            var meatList = new ShoppingList()
            {
                new ShoppingItem() { ProductName="Beef", ProductQuantity=7},
                new ShoppingItem() { ProductName="Chicken", ProductQuantity=3},
                new ShoppingItem() { ProductName="Pork", ProductQuantity=5},
            };
            meatList.Heading = "Meats";
            var fruitList = new ShoppingList()
            {
                new ShoppingItem() { ProductName="Apples", ProductQuantity=12},
                new ShoppingItem() { ProductName="Bananas", ProductQuantity=6},
                new ShoppingItem() { ProductName="Peaches", ProductQuantity=4},
            };
            fruitList.Heading = "Fruits";
            var vegetableList = new ShoppingList()
            {
                new ShoppingItem() { ProductName="Corn", ProductQuantity=8},
                new ShoppingItem() { ProductName="Potatoes", ProductQuantity=9},
                new ShoppingItem() { ProductName="Green Beans", ProductQuantity=8},
                new ShoppingItem() { ProductName="Broccoli", ProductQuantity=1}
            };
            vegetableList.Heading = "Vegetables";
            DisplayList = new List<ShoppingList>()
            {
                meatList,
                fruitList,
                vegetableList
            };
            Search = new Command(async () =>
            {
                ShoppingList tempList = new ShoppingList();
                tempList.Heading = "Search Results";
                RestHelper restH = new RestHelper();
                JObject sRes = await restH.GetKroger(SearchText);
                foreach (var currItem in sRes["data"])
                {
                    tempList.Add(new ShoppingItem() { ProductName = currItem["description"].ToString(), ProductQuantity = 0, ProductSize = currItem["items"][0]["size"].ToString()});
                }
                DisplayList = new List<ShoppingList>() { tempList };
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("DisplayList"));

            });
        }

        public List<ShoppingList> DisplayList
        {
            get
            {
                if (IsSearchingBool.IsSearchingInstance.getIsSearching())
                {
                    Debug.WriteLine("RETURNING SEARCH RESULTS");
                    return _SearchResults;
                } else
                {
                    Debug.WriteLine("RETURNING GROCERY LIST");
                    return _ListOfShoppingList;
                }
            }
            set
            {
                if (IsSearchingBool.IsSearchingInstance.getIsSearching())
                {
                    _SearchResults = value;
                } else
                {
                    _ListOfShoppingList = value;
                }
                base.OnPropertyChanged();
            }
        }

        public String SearchText
        {
            set
            {
                if (value.Length == 0 && IsSearchingBool.IsSearchingInstance.getIsSearching() == true)
                {
                    IsSearchingBool.IsSearchingInstance.setIsSearching(false);
                    PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("DisplayList"));
                } else if (value.Length > 0 && IsSearchingBool.IsSearchingInstance.getIsSearching() == false)
                {
                    IsSearchingBool.IsSearchingInstance.setIsSearching(true);
                    Search.CanExecute(this);
                }
                _searchText = value;
                base.OnPropertyChanged();
            }
            get
            {
                return _searchText;
            }
        }

        public ICommand Search
        {
            get; private set; 
        }

        public ICommand ButtonClicked
        {
            get
            {
                Debug.WriteLine("in button clicked");
                if (IsSearchingBool.IsSearchingInstance.getIsSearching())
                {
                    Debug.WriteLine("is searching");
                    return new Command<String>((itemName) => {
                        Debug.WriteLine(itemName);
                        Debug.WriteLine(_SearchResults[0].ToString());
                        Debug.WriteLine(_ListOfShoppingList[0].ToString());
                        ShoppingItem temp = _SearchResults[0].Find(x => x.ProductName.Equals(itemName));
                        _SearchResults[0].Remove(temp);
                        _ListOfShoppingList[0].Add(temp);
                        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("DisplayList"));
                    });
                } else
                {
                    Debug.WriteLine("Not searching");
                    return new Command(() => { });
                }
            }
        }
    }
Command="{Binding Path=BindingContext.ButtonClicked, Source={x:Reference MyListView}}" />