【问题标题】:Command bindings are not working in item template命令绑定在项目模板中不起作用
【发布时间】:2020-11-18 10:19:43
【问题描述】:

命令不适用于 MVVM 模式中的资源。我尝试使用祖先和视图模型 (CustomersViewModel) 设置源,并使用对父内容页面 (CustomersView) 的引用。数据显示正常,问题仅在于未触发的命令。

<CollectionView x:Name="CollectionView"  ItemsSource="{Binding Customers}"
                         ItemTemplate="{StaticResource customerDataTemplateSelector}">
                     </CollectionView>

ContentPage.Resources

<ContentPage.Resources>
    <ResourceDictionary>

        <DataTemplate x:Key="customerTemplate">
            <Grid BackgroundColor="{StaticResource NoColor}" Padding="10,5">
                <Grid.RowDefinitions>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                    <RowDefinition Height="Auto"/>
                </Grid.RowDefinitions>
                <Label Grid.Row="0" Text="{Binding Name}" LineBreakMode="WordWrap" FontSize="Medium" LineHeight="1.1"/>

                <Grid Grid.Row="1">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="1"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="25*"/>
                        <ColumnDefinition Width="75*"/>
                    </Grid.ColumnDefinitions>

                    <!-------THIS IS NOT WORKING WITH Ancestor Type--------->

                    <StackLayout Grid.Column="0" Grid.Row="1" Spacing="2" Padding="0"  Orientation="Horizontal">
                        <Label FontFamily="{StaticResource FontAwesomeSolid}" VerticalOptions="Center" Text="{x:Static fontawesome:FontAwesomeIcons.Share}" Style="{StaticResource LiteDarkLabelStyle}"></Label>
                        <Label Text="Share"  Style="{StaticResource ListItemFooterLabelStyle}"/>
                        <StackLayout.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding BindingContext.ShareCustomerCommand, Source={RelativeSource AncestorType={x:Type local:CustomersViewModel}}}" CommandParameter="{Binding .}" NumberOfTapsRequired="1">
                            </TapGestureRecognizer>
                        </StackLayout.GestureRecognizers>
                    </StackLayout>

                    <!-------EVEN THIS IS NOT WORKING - setting source as parent content page--------->

                    <StackLayout Grid.Column="1" Grid.Row="1" Spacing="2" Padding="0" HorizontalOptions="StartAndExpand"  Orientation="Horizontal">
                        <Label FontFamily="{StaticResource FontAwesomeSolid}" VerticalOptions="Center" Text="{x:Static fontawesome:FontAwesomeIcons.Favorite}" TextColor="{Binding IsFavorite, Converter={Helpers:Highlighter}}"></Label>
                        <Label Text="Favorite" TextColor="{Binding IsFavorite, Converter={Helpers:Highlighter}}"/>
                        <StackLayout.GestureRecognizers>
                            <TapGestureRecognizer Command="{Binding BindingContext.FavoriteCustomerCommand, Source={x:Reference CustomersView}}" CommandParameter="{Binding .}" NumberOfTapsRequired="1">
                            </TapGestureRecognizer>
                        </StackLayout.GestureRecognizers>
                    </StackLayout>
                </Grid>

                <BoxView Grid.Row="2" HeightRequest="8"
                                   BackgroundColor="{StaticResource LiteColor}"
                                   HorizontalOptions="FillAndExpand"
                                   VerticalOptions="FillAndExpand"/>
            </Grid>
        </DataTemplate>

        <DataTemplate x:Key="customerReadModeTemplate">
            <StackLayout Padding="10,0" BackgroundColor="{StaticResource NoColor}">
                <Label LineBreakMode="WordWrap" LineHeight="1.1">
                    <Label.FormattedText>
                        <FormattedString>
                            <FormattedString.Spans>
                                <Span Text="{Binding Name}" FontSize="Small"/>
                                <Span Text=". " />
                                <Span Text="{Binding City}" FontSize="Medium" />
                            </FormattedString.Spans>
                        </FormattedString>
                    </Label.FormattedText>
                </Label>
            </StackLayout>
        </DataTemplate>


        <Helpers:CustomerDataTemplateSelector x:Key="customerDataTemplateSelector"
            CustomerReadModeTemplate="{StaticResource customerReadModeTemplate}"
            CustomerTemplate="{StaticResource customerTemplate}"
            />
    </ResourceDictionary>
</ContentPage.Resources>

编辑 另外,我尝试设置相对来源

<ContentPage ..
BindingContext="{Binding Source={RelativeSource Self}, Path=ViewModel}">

在页面中

public partial class CustomersPage {
 public CustomersPage ()
 {
      var customersService = new CustomersService();
      ViewModel = new CustomersViewModel(customersService);
 }
  public CustomersViewModel ViewModel { get; set; }
}

另外,我最初也有这个,但也没有用。

    public CustomersViewModel ViewModel
    {
        get { return BindingContext as CustomersViewModel; }
        set { BindingContext = value; }
    }

【问题讨论】:

    标签: xamarin xamarin.forms


    【解决方案1】:

    您的 BindingSource 是一个 ViewModel,您不需要将路径设置为 BindingContext.ShareCustomerCommand

    BindingContext.ShareCustomerCommand 更改为ShareCustomerCommand 应该可以工作:

    <TapGestureRecognizer Command="{Binding ShareCustomerCommand, Source={RelativeSource AncestorType={x:Type local:CustomersViewModel}}}" CommandParameter="{Binding .}" NumberOfTapsRequired="1">
    

    更新

    Xaml 中的代码:

    <CollectionView ItemsSource="{Binding Customers}">
        <CollectionView.ItemTemplate>
            <DataTemplate>
                <Grid  Padding="10,5">
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                        <RowDefinition Height="Auto"/>
                    </Grid.RowDefinitions>
                    <Label Grid.Row="0" Text="Name" LineBreakMode="WordWrap" FontSize="Medium" LineHeight="1.1"/>
    
                    <Grid Grid.Row="1">
                        <Grid.RowDefinitions>
                            <RowDefinition Height="1"/>
                            <RowDefinition Height="Auto"/>
                        </Grid.RowDefinitions>
                        <Grid.ColumnDefinitions>
                            <ColumnDefinition Width="25*"/>
                            <ColumnDefinition Width="75*"/>
                        </Grid.ColumnDefinitions>
    
    
                        <StackLayout Grid.Column="0" Grid.Row="1" Spacing="2" Padding="0"  Orientation="Horizontal">
                            <Label  VerticalOptions="Center" Text="fontawesome:FontAwesomeIcons.Share"></Label>
                            <Label Text="Share" />
                            <StackLayout.GestureRecognizers>
                                <TapGestureRecognizer Command="{Binding OnTextboxLostFocus, Source={RelativeSource AncestorType={x:Type local:CustomersViewModel}}}" CommandParameter="{Binding .}" NumberOfTapsRequired="1">
                                </TapGestureRecognizer>
                            </StackLayout.GestureRecognizers>
                        </StackLayout>
                    </Grid>
                </Grid>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
    

    .cs 中的代码:

    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
    
            BindingContext = new CustomersViewModel();
        }
    }
    
    public class CustomersViewModel
    {
        public ObservableCollection<Document> Customers { get; set; }
        public Command OnTextboxLostFocus { get; }
        public Command OnTextboxGotFocus { get; }
    
        public CustomersViewModel()
        {
            OnTextboxLostFocus = new Command(OnTextboxLostFocusMethod);
            OnTextboxGotFocus = new Command(OnTextboxGotFocusMethod);
    
            Customers = new ObservableCollection<Document>();
    
            Customers.Add(new Document() );
            Customers.Add(new Document() );
            Customers.Add(new Document() );
            Customers.Add(new Document() );
        }
    
        public void OnTextboxLostFocusMethod(object sender)
        {
            Console.WriteLine("OnTextboxLostFocusMethod");
        }
    
        public void OnTextboxGotFocusMethod(object sender)
        {
            Console.WriteLine("OnTextboxGotFocusMethod");
        }
    }
    
    public class Document
    {
    
    }
    

    【讨论】:

    • 另外,尝试将相对源自身添加到内容页面(如上面的代码所示)
    • 嗯,它适用于我,我已经更新了我的代码示例。
    • 你也可以试试the answer in this thread
    • 非常感谢,我的命令签名不正确。它现在正在工作。
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2013-10-03
    • 1970-01-01
    • 1970-01-01
    • 2016-10-02
    • 1970-01-01
    相关资源
    最近更新 更多