maui - Command not getting triggered after enabling compiled bindings in CollectionView, TapGestureRecognizer - Stack Overflow

To use compiled bindings I have enabled this from csproject file:<MauiEnableXamlCBindingWithSourceC

To use compiled bindings I have enabled this from csproject file:

<MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>

Now, after enabling this my Command property stopped working in multiple places. I have followed the maui-samples for 9 and added the x:DataType using relative source as shown in the sample.

For reference: .0/UserInterface/Views/CollectionViewDemos/CollectionViewDemos/Views/Swipe/VerticalListSwipeContextItemsPage.xaml#L20

<ContentView
    x:Class="Sample.UI.InspectionOverview.ObjectListView"
    xmlns=";
    xmlns:x=";
    xmlns:vm="clr-namespace:Sample.UI.InspectionOverview;assembly=Sample.UI"
    xmlns:data="clr-namespace:Sample.Models.ViewModels.Object;assembly=Sample.Models"
    xmlns:inspectionControl="clr-namespace:Sample.UI.Controls.Object"
    x:Name="_objectListView"
    x:DataType="vm:InspectionOverviewPageViewModel">
    <CollectionView
        ItemsSource="{Binding Path=ObjectList}"
        BackgroundColor="{AppThemeBinding Light={StaticResource LightGray}, Dark={StaticResource DarkGray}}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="data:ObjectViewModel">
                <inspectionControl:ObjectCard
                    ObjectInfo="{Binding}"
                    ObjectTappedCommand="{Binding x:DataType='vm:InspectionOverviewPageViewModel', Source={RelativeSource AncestorType={x:Type vm:InspectionOverviewPageViewModel}}, Path=ObjectItemTappedCommand}"/>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentView>

Same issue when I using Command with Relative source on TapGestureRecognizer in control's like Image, Label etc.

If I use command like this:

ObjectTappedCommand="{Binding x:DataType='vm:InspectionOverviewPageViewModel', 
Path=BindingContext.ObjectItemTappedCommand, Source={x:Reference 
Name=_objectListView}}"

Then it did work but it gives Binding: Property "BindingContext" not found on "Sample.UI.InspectionOverview.InspectionOverviewPageViewModel". maui(XC0045)

To remove this warnings I have to use RelativeSource style and remove BindingContext but in that case Command is not getting triggered. How to handle this?

To use compiled bindings I have enabled this from csproject file:

<MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>

Now, after enabling this my Command property stopped working in multiple places. I have followed the maui-samples for 9 and added the x:DataType using relative source as shown in the sample.

For reference: https://github/dotnet/maui-samples/blob/main/9.0/UserInterface/Views/CollectionViewDemos/CollectionViewDemos/Views/Swipe/VerticalListSwipeContextItemsPage.xaml#L20

<ContentView
    x:Class="Sample.UI.InspectionOverview.ObjectListView"
    xmlns="http://schemas.microsoft/dotnet/2021/maui"
    xmlns:x="http://schemas.microsoft/winfx/2009/xaml"
    xmlns:vm="clr-namespace:Sample.UI.InspectionOverview;assembly=Sample.UI"
    xmlns:data="clr-namespace:Sample.Models.ViewModels.Object;assembly=Sample.Models"
    xmlns:inspectionControl="clr-namespace:Sample.UI.Controls.Object"
    x:Name="_objectListView"
    x:DataType="vm:InspectionOverviewPageViewModel">
    <CollectionView
        ItemsSource="{Binding Path=ObjectList}"
        BackgroundColor="{AppThemeBinding Light={StaticResource LightGray}, Dark={StaticResource DarkGray}}">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="data:ObjectViewModel">
                <inspectionControl:ObjectCard
                    ObjectInfo="{Binding}"
                    ObjectTappedCommand="{Binding x:DataType='vm:InspectionOverviewPageViewModel', Source={RelativeSource AncestorType={x:Type vm:InspectionOverviewPageViewModel}}, Path=ObjectItemTappedCommand}"/>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentView>

Same issue when I using Command with Relative source on TapGestureRecognizer in control's like Image, Label etc.

If I use command like this:

ObjectTappedCommand="{Binding x:DataType='vm:InspectionOverviewPageViewModel', 
Path=BindingContext.ObjectItemTappedCommand, Source={x:Reference 
Name=_objectListView}}"

Then it did work but it gives Binding: Property "BindingContext" not found on "Sample.UI.InspectionOverview.InspectionOverviewPageViewModel". maui(XC0045)

To remove this warnings I have to use RelativeSource style and remove BindingContext but in that case Command is not getting triggered. How to handle this?

Share Improve this question edited Mar 20 at 12:30 Divyesh asked Mar 20 at 12:18 DivyeshDivyesh 2,41727 silver badges47 bronze badges 0
Add a comment  | 

2 Answers 2

Reset to default 1

I use RelativeSource style binding as you said and trigger the command successfully.

ObjectTappedCommand="{Binding  Source={RelativeSource  AncestorType={x:Type vm:InspectionOverviewPageViewModel}}, Path=ObjectItemTappedCommand, x:DataType=vm:InspectionOverviewPageViewModel}"/>

Just make a small demo as below.

For convenience, I use a simple layout for ObjectCard, which has two BindableProperties.

Here is the code behind for it. I just define the BindableProperties for it,

public partial class ObjectCard : ContentView
{

    public static readonly BindableProperty ObjectInfoProperty =
    BindableProperty.Create("ObjectInfo", typeof(string), typeof(ObjectCard), "false");
    public string ObjectInfo
    {
        get => (string)GetValue(ObjectInfoProperty);
        set => SetValue(ObjectInfoProperty, value);
    }

    public static readonly BindableProperty ObjectTappedCommandProperty =
    BindableProperty.Create("ObjectTappedCommand", typeof(Command), typeof(ObjectCard), null);

    public Command ObjectTappedCommand
    {
        get => (Command)GetValue(ObjectTappedCommandProperty);
        set => SetValue(ObjectTappedCommandProperty, value);
    }

    public ObjectCard()
    {
        InitializeComponent();
    }
}

Here is the xaml. I use a Button and bind its Command to the BindableProperty. To avoid mismatch of bindings, I also explicitly set the x:DataType for the Binding.

<ContentView xmlns="http://schemas.microsoft/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft/winfx/2009/xaml"
             x:Class="MauiApp.ObjectCard"
             xmlns:vm="clr-namespace:MauiApp"
             x:DataType="vm:ObjectViewModel"
             x:Name="this">
    <VerticalStackLayout>
        <Label 
            Text="{Binding Name}"
            VerticalOptions="Center" 
            HorizontalOptions="Center" />

        <Button Text="click me to trigger the command"  
                Command="{Binding Source={x:Reference this}, Path=ObjectTappedCommand, x:DataType='vm:ObjectCard'}"                                             
                />
    </VerticalStackLayout>
</ContentView>

You may also use RelativeBinding for the Command, which also works.

<Button Text="click me to trigger the command"  
        Command="{Binding Source={RelativeSource AncestorType={x:Type vm:ObjectCard}}, Path=ObjectTappedCommand, x:DataType=vm:ObjectCard}"                          
        />

After that even you set the

<MauiEnableXamlCBindingWithSourceCompilation>true</MauiEnableXamlCBindingWithSourceCompilation>

in the project file, the command can also be triggered.


Update

The code for ContentView, the BindingContext of which inherits from the parent ContentPage.

<ContentView xmlns="http://schemas.microsoft/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft/winfx/2009/xaml"
             x:Class="MauiApp.MyContentView"
             ...
             x:DataType="vm:InspectionOverviewPageViewModel">

    <CollectionView
        ItemsSource="{Binding Path=ObjectList}"
        BackgroundColor="Green">
        <CollectionView.ItemTemplate>
            <DataTemplate x:DataType="data:ObjectViewModel">
                <inspectionControl:ObjectCard x:DataType="data:ObjectViewModel"
                    ObjectInfo="{Binding}"
                    ObjectTappedCommand="{Binding  Source={RelativeSource  AncestorType={x:Type vm:InspectionOverviewPageViewModel}}, Path=ObjectItemTappedCommand, x:DataType=vm:InspectionOverviewPageViewModel}"/>
            </DataTemplate>
        </CollectionView.ItemTemplate>
    </CollectionView>
</ContentView>

Assumptions:

  • The ObjectItemTappedCommand exist on your view model named InspectionOverviewPageViewModel
  • The view model InspectionOverviewPageViewModel is set to the BindingContext of your ObjectListView.

So, the Path, x:DataType and the Source should be changed to:

ObjectTappedCommand="{Binding BindingContext.ObjectItemTappedCommand,
                              x:DataType=ContentView,
                              Source={Reference _objectListView}}"

The problem with this is your compiled bindings only work to lookup ContentView.BindingContext but there's no compiled time clarification that BindingContext is of type vm:InspectionOverviewPageViewModel. To do need to do more things in your ObjectListView code-behind to copy and expose your view model as a property on ObjectListView instead of it being set to the BindingContext.

发布者:admin,转转请注明出处:http://www.yc00.com/questions/1744410331a4572841.html

相关推荐

发表回复

评论列表(0条)

  • 暂无评论

联系我们

400-800-8888

在线咨询: QQ交谈

邮件:admin@example.com

工作时间:周一至周五,9:30-18:30,节假日休息

关注微信