Search code examples
c#.netmauimaui-community-toolkit

Cancel Image.Source replacement if the condition in the Drop command is not matched


Hi friends, I have problem when dragged Image is replace an image that implements the DropCommnad command even if the if condition inside the DropCommand is not matched.

I have an Image in xaml:

<Image x:Name="chooseImage"
       IsVisible="{Binding IsVisible}"
       Source="{Binding ImageRoute}"
       Opacity="{Binding BindingContext.CarImageOpacity, Source={x:Reference ActivePage}}"
       Aspect="AspectFit"
       WidthRequest="120">
    <Image.GestureRecognizers>
        <DragGestureRecognizer
            
            CanDrag="True"
            DropCompletedCommand="{Binding BindingContext.DragCompletedCommand , Source={x:Reference ActivePage}}"
            DropCompletedCommandParameter="{Binding .}"
            DragStartingCommand="{Binding BindingContext.DragStartingCommand ,Source={x:Reference ActivePage}}"
            DragStartingCommandParameter="{Binding .}">
        </DragGestureRecognizer>
    </Image.GestureRecognizers>
</Image>```

It's base on CollectionView (cars).

And one Image for drop (where dragged image will be dropped):

<Image x:Name="FirstImage"
       Grid.Row="1" BackgroundColor="Yellow"
       HeightRequest="120" WidthRequest="120"
       HorizontalOptions="Center"
       Source="{Binding FirstImageCardSource}"
       IsVisible="true"
       Opacity="{Binding FirstCardOpacity}"
       VerticalOptions="End"
       Aspect="Fill">
    <Image.GestureRecognizers>
        <DropGestureRecognizer AllowDrop="True"
                              DropCommandParameter="{x:Reference FirstImage}"
                              DropCommand="{Binding BindingContext.DropCommand, Source={x:Reference ActivePage}}"/>
    </Image.GestureRecognizers>
</Image>

So, main problem right inside my ViewModel, there is my Drag and Drop commands:

[RelayCommand]
private void DragStarting(object e)
{
    DragItem = e as Car;

    DragItem.IsVisible = false;
}

[RelayCommand]
private void Drop(object e)
{
    Image takingImage = e as Image;

    // Get the image source string
    string imageSource = takingImage.Source.ToString();

    // Replace "File: " with an empty string
    string fileName = imageSource.Replace("File: ", "");

    // Compare the file names
    if (DragItem.ImageRoute == fileName)
    {
        Console.WriteLine("Something cool");]
    }
    else
    {
        Console.WriteLine("Incorrect match. Do not change the image source.");
        return;
    }
    //else code
}

When a mismatch occurs, it is called a return; but the Source of the image where the Drop occurred is still changed. How to fix this? I have tried everything (OneWay Binding varius Properties and others), can you help me in any way?


Solution

  • You can use the following code to achieve it:

    <Image Source="dsc.JPG"
           WidthRequest="200"
           HeightRequest="150"
           Aspect="AspectFit">
        <Image.GestureRecognizers>
            <DragGestureRecognizer />
        </Image.GestureRecognizers>
    </Image>
    
    
    <Image x:Name="FirstImage"
           Source="dsd.JPG"
           BackgroundColor="Silver"
           WidthRequest="400"
           HeightRequest="300"
           Aspect="AspectFill">
        <Image.GestureRecognizers>
            <DropGestureRecognizer DragOver="DropGestureRecognizer_DragOver" x:Name="drop"/>
        </Image.GestureRecognizers>
    </Image>
    

    Code behind:

    private void DropGestureRecognizer_DragOver(object sender, DragEventArgs e)
    {
        var i = FirstImage.Source.ToString();
        var j = e.Data.Image.ToString();
        if (i != j)
        {
            drop.AllowDrop = false;
        }
    }
    

    And here is the effect.

    I also tried to implement it in ViewModel but failed. Adding a breakpoint to run is ok, but runnig it directly will still change the image. It's weird.