在Xamarin中获取从模板到视图模型的click命令

时间:2018-08-20 15:55:27

标签: visual-studio xamarin xamarin.forms

在模板中有一个按钮,其创建如下,名为x:Name =“ cartbutton”

<?xml version="1.0" encoding="UTF-8"?>
<Grid xmlns="http://xamarin.com/schemas/2014/forms"
    xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml" 
    xmlns:ffimageloading="clr-namespace:FFImageLoading.Forms;assembly=FFImageLoading.Forms" 
    x:Class="FormsApplication.Templates.ListItemTemplate" 
    xmlns:controls="clr-namespace:FormsControls.Base;assembly=FormsControls.Base"
    ColumnSpacing="0" RowSpacing="0" HeightRequest="350" Padding="8,0,8,8" x:Name="ListItemTempPage">
    <Grid.RowDefinitions>
        <RowDefinition Height="300" />
        <RowDefinition Height="30" />
        <RowDefinition Height="30"/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition Width="*"/>
    </Grid.ColumnDefinitions>
    <controls:RoundedBoxView Grid.RowSpan="2" BackgroundColor="White" BorderColor="Silver" CornerRadius="8" BorderThickness="2"/>
    <ffimageloading:CachedImage Grid.RowSpan="2" Source="{Binding ImageSource}" Aspect="AspectFill" DownsampleToViewSize="False"/>
    <Button x:Name="cartbutton" Grid.Row="0" HorizontalOptions="End" VerticalOptions="Start" Image="lowim.png" BackgroundColor="Transparent" Margin="0,5,5,0" Command="{Binding ParentContext.Itemtapped, Source={x:Reference ListItemTempPage}}" CommandParameter="{Binding .}"/>
</Grid>

,并且引用将父页面称为模板,如下所示

<ListView x:Name="listView" Grid.Row="1" Margin="0,8,0,0"
            HasUnevenRows="true" ItemsSource="{Binding FoodItems}"
            SeparatorColor="Transparent" SeparatorVisibility="None">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <templates:ListItemTemplate ParentContext="{Binding BindingContext, Source={x:Reference ListItemPage}}"/>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
            <ListView.Behaviors>
                <controls:EventToCommandBehavior EventName="ItemTapped" Command="{Binding ListItemTappedCommand}" CommandParameter="{x:Reference listView}"/>
            </ListView.Behaviors>
        </ListView>

最后,viewmodel与icommand一起使用,如下所示

 public SelectItemViewModel(IAppContext context, IRestService restService) : base(context)
        {
            _restService = restService;
            Title = "Category Products";
            ListItemTappedCommand = new Command<ListView>(OnListItemTappedCommand);
            PageAppearingCommand = new Command(OnPageAppearingCommand);
            Itemtapped = new Command(OnItemtapped);
        }

        public ICommand Itemtapped { get; }

        private void OnItemtapped()
        {
            Navigator.PushAsync<SelectItemViewModel>();
        }

所以在编译时会显示错误消息

 No property, bindable property, or event found for 'ParentContext', or mismatching type between value and property.    

所以基本上说我无法在视图模型中正确发出按钮命令(在模板页面中),将不胜感激,感谢您的帮助。

1 个答案:

答案 0 :(得分:0)

我将在您的子控件中引入AddToCartCommand,如果单击该按钮,则会调用该控件。

// in your ListItemTemplate.xaml.cs
public static BindableProperty AddToCartCommandProperty = BindableProperty.Create(/* ... */);

public ICommand AddToCartCommand
{
   get => (ICommand)GetValue(AddToCartCommandProperty);
   set => SetValue(AddToCartCommandProperty, value);
}

public void Button_OnClick(object sender, EventArgs e)
{
    this.AddToCartCommand?.Execute(null);
}

要从父视图绑定到此视图,您需要使用x:Name="Page"对该父视图的引用(或者您想为页面命名),然后使用{Binding Source={x:Reference Page}, Path=BindingContext.Itemtapped} < / p>

<ContentPage ... x:Name="Page"> <!-- I have elided attributes that are not relevant to my answer -->
    <!-- Elided -->
    <ListView ...>
        <ListView.ItemTemplate>
            <DataTemplate>
                <ViewCell>
                    <templates:ListItemTemplate AddToCartCommand="{Binding Source={x:Reference Page}, Path=BindingContext.Itemtapped}" />
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
        <!-- Elided -->
    </ListView>
    <!-- Elided -->
</ContentPage>