首页 > 解决方案 > 泛型控件中的绑定为空

问题描述

我有几个通用按钮。标题和相应的图标都正确显示,但点击功能不起作用。

带有 ScanningApp 控件的 HomePage.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             x:Class="primetals.ScannerApp.Views.HomePage"
             xmlns:controls="clr-namespace:primetals.ScannerApp.Controls"
             xmlns:resource="clr-namespace:primetals.ScannerApp"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             BackgroundColor="White"
             x:Name="self"
             Title="{Binding Title}">
    <ContentPage.Resources>
        <ResourceDictionary>
            <Style TargetType="controls:ScanningApp">
                <Setter Property="WidthRequest" Value="220"></Setter>
                <Setter Property="HeightRequest" Value="220"></Setter>
            </Style>
        </ResourceDictionary>
    </ContentPage.Resources>

    <Grid Margin="10">
        <Grid.RowDefinitions>
            <RowDefinition Height="3*"></RowDefinition>
            <RowDefinition Height="3*"></RowDefinition>
            <RowDefinition x:Name="backgroundImageRow" Height="4*"></RowDefinition>
        </Grid.RowDefinitions>

        <StackLayout Grid.Row="0" HorizontalOptions="CenterAndExpand" Margin="0,10,0,10">
            <!-- Application Logo -->
            <Image Source="icon_scannerapp.png" WidthRequest="96" HeightRequest="96"></Image>

            <!-- Welcome Text -->
            <Label Text="{x:Static resource:ApplicationResources.WelcomeMessageLine1}" FontSize="Large">
            </Label>
            <Label FontSize="Large">
                <Label.FormattedText>
                    <FormattedString>
                        <Span Text="{x:Static resource:ApplicationResources.WelcomeMessageLine2}"></Span>
                        <Span Text="{x:Static resource:ApplicationResources.WelcomeMessageSpareParts}" FontAttributes="Bold" FontSize="Large"></Span>
                        <Span Text="{x:Static resource:ApplicationResources.WelcomeMessageOr}"></Span>
                        <Span Text="{x:Static resource:ApplicationResources.WelcomeMessageSensorData}" FontAttributes="Bold"  FontSize="Large"></Span>
                        <Span Text="!"></Span>
                    </FormattedString>
                </Label.FormattedText>
            </Label>
        </StackLayout>

        <!-- Scanning Applications -->
        <StackLayout Orientation="Horizontal" Grid.Row="1" BindableLayout.ItemsSource="{Binding Apps}" HorizontalOptions="Center" VerticalOptions="Start">
            <BindableLayout.ItemTemplate>
                <DataTemplate>
                    <controls:ScanningApp Margin="0,0,5,0"
                        ImageSource="{Binding ImageUrl}"
                        TapImageSource="{Binding TapImageUrl}"
                        Text="{Binding Title}"
                        TappedCommand="{Binding BindingContext.AppTappedCommand, Source={x:Reference self}}"
                        TappedCommandParameter="{Binding}">
                    </controls:ScanningApp>
                </DataTemplate>
            </BindableLayout.ItemTemplate>

        </StackLayout>

        <!-- Background Image -->
        <Image x:Name="backgroundImage" Grid.Row="2" Source="background_scannerapp_PT.jpg" Aspect="AspectFit" HorizontalOptions="Fill" VerticalOptions="Fill"></Image>
    </Grid>
</ContentPage>

HomepageViewModel.cs: AppTappedCommand设置正确

    this.AppTappedCommand = new DelegateCommand<ScanApplication>((app) => OnGotoScanPage(app));
    this.Title = ApplicationResources.ApplicationTitleCaption;

    public async void OnGotoScanPage(ScanApplication app)
    {
        NavigationParameters parameters = new NavigationParameters();
        parameters.Add(Constants.Parameters.App, app.AppId);
        await this.NavigationService.NavigateAsync($"{nameof(ScanPage)}", parameters);
    }

ScanningApp.xaml.cs:单击按钮后TappedCommand为空。

    public static readonly BindableProperty TappedCommandProperty = BindableProperty.Create(nameof(TappedCommand), typeof(ICommand), typeof(ScanningApp), default(ICommand), Xamarin.Forms.BindingMode.OneWay);
    public ICommand TappedCommand
    {
        get
        {
            return (ICommand)GetValue(TappedCommandProperty);
        }
        set
        {
            SetValue(TappedCommandProperty, value);
        }
    }
    
    public static readonly BindableProperty TappedCommandParameterProperty = BindableProperty.Create(nameof(TappedCommandParameter), typeof(object), typeof(ScanningApp), null, Xamarin.Forms.BindingMode.OneWay);
    public object TappedCommandParameter
    {
        get
        {
            return GetValue(TappedCommandParameterProperty);
        }
        set
        {
            SetValue(TappedCommandParameterProperty, value);
        }
    }
    
    private bool OnExecuteTap()
    {
        img.Source = this.ImageSource;

        if (this.TappedCommand != null && this.TappedCommand.CanExecute(this.TappedCommandParameter))
        {
            this.TappedCommand.Execute(this.TappedCommandParameter);
        }

        return false;
    }

扫描应用程序.xaml

<?xml version="1.0" encoding="utf-8" ?>
<ContentView xmlns="http://xamarin.com/schemas/2014/forms"
             xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
             xmlns:prism="clr-namespace:Prism.Mvvm;assembly=Prism.Forms"
             prism:ViewModelLocator.AutowireViewModel="True"
             x:Class="primetals.ScannerApp.Controls.ScanningApp"
             x:Name="self">
    <Grid Padding="1" BackgroundColor="{StaticResource PrimetalsLightGrayColor}">
        <Grid>
            <Grid.GestureRecognizers>
                <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>
            </Grid.GestureRecognizers>
            <Grid.RowDefinitions>
                <RowDefinition Height="5*"></RowDefinition>
                <RowDefinition Height="1*" ></RowDefinition>
            </Grid.RowDefinitions>

            <Image x:Name="img" Grid.Row="0" Source="{Binding ImageSource, Source={x:Reference self}}" Aspect="AspectFit" VerticalOptions="CenterAndExpand"
                   Margin="20"></Image>
            
            <Label Grid.Row="1" Text="{Binding Text, Source={x:Reference self}}" 
                   Margin="10,0,10,10"
                   FontSize="Medium" TextColor="{StaticResource PrimetalsAccentColor}"
                   VerticalTextAlignment="Center" HorizontalTextAlignment="Center"></Label>
        </Grid>
    </Grid>

</ContentView>

最初这个源代码有效(大约一年前)(但 VS 中的新包可能存在问题)。我希望你能帮助我。非常感谢!

br

标签: c#xamarin.formsxamarin.android

解决方案


您的代码中似乎应该有一个TapGestureRecognizer_Tapped事件处理程序ScanningApp.xaml.cs

<TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped"></TapGestureRecognizer>

所以你可以这样做:

private void TapGestureRecognizer_Tapped(object sender, EventArgs e)
    {
        img.Source = this.ImageSource;
        if (this.TappedCommand != null && this.TappedCommand.CanExecute(this.TappedCommandParameter))
        {
            this.TappedCommand.Execute(this.TappedCommandParameter);
        }
    }

推荐阅读