PropertyChanged 事件在第一次运行时不反映新的 Image.Source

如何解决PropertyChanged 事件在第一次运行时不反映新的 Image.Source

我正在开发移动应用程序,有点通过按顺序拖放图像来模拟如何构建台式计算机。我使用 DropGestureRecognizerAllowDrop 设置为 True 用于放置区 Image 控件和 DragGestureRecognizer 并将 CanDrag 设置为 True用于拖动 Image 对象。

这个想法是 Drag Image Objects 会被拖放到 Drop Zone Image Control 上,如果他们放下了正确的 Drag ImageDrop Zone 会接受它作为 {{1 }} 和另一个 Image.source 将堆叠在它的前面以与下一个台式计算机组件一起使用。否则,它将被拒绝,Drop Zone 将设置为 Image.sourceempty

但是,我遇到了一个奇怪的问题,在拖动的第一个不正确的图像上,null属性重置为 Image.sourceempty,但在实际的 UI 上,它没有。在随后的 EventHandler 执行中,它确实会被重置。我在 null 上有一个 TapGestureRecognizer 来检查是否有 Drop Zone 集。

如果我的解释有点混乱,我很抱歉,因为英语不是我的母语,我很难解释。所以请参考下面的 GIF 示例和我的代码

视图(.xaml):

Image.source

查看代码 (.xaml.cs):

<ContentPage.Content>
    <Grid RowDeFinitions="Auto,60,*"
          ColumnDeFinitions="*">

        <RelativeLayout Grid.Row="0" Grid.Column="0" HorizontalOptions="Center">
            <Image x:Name="imgCaseDropZone"
                   RelativeLayout.XConstraint="0"
                   RelativeLayout.YConstraint="0"
                   HeightRequest="{Binding ScreenWidth}"
                   WidthRequest="{Binding ScreenWidth}"
                   PropertyChanged="CaseDropZone_PropertyChanged"
                   BackgroundColor="LightGray">
                <Image.GestureRecognizers>
                    <DropGestureRecognizer AllowDrop="True" />
                    <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
                </Image.GestureRecognizers>
            </Image>
        </RelativeLayout>

        <Label Grid.Row="1" Grid.Column="0"
               x:Name="lblDirections"
               Text="Directions: Drag the components below in its proper order to the drop zone above."
               TextColor="Black"
               Padding="10"
               VerticalOptions="CenterandExpand" 
               HorizontalOptions="CenterandExpand" />

        <ScrollView Grid.Row="2"
                    Orientation="Horizontal"
                    Margin="5">
            <StackLayout Orientation="Horizontal">

                <!--#region Case -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding CaseIsVisible}">
                    <Image Grid.Row="0"
                           x:Name="imgCaseDragObject"
                           Source="{Binding CaseImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding CaseLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Case Cover -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding CaseCoverIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding CaseCoverImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding CaseCoverLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Case Screw -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding CaseScrewIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding CaseScrewImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding CaseScrewLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Hard disk Drive -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding HarddiskDriveIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding HarddiskDriveImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding HarddiskDriveLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Heatsink -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding HeatsinkIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding HeatsinkImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding HeatsinkLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Memory Module -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding MemoryModuleIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding MemoryModuleImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding MemoryModuleLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region motherboard -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding motherboardIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding motherboardImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding motherboardLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region motherboard Screw -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding motherboardScrewIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding motherboardScrewImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding motherboardScrewLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Power Supply -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding PowerSupplyIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding PowerSupplyImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding PowerSupplyLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

                <!--#region Processor -->
                <Grid RowDeFinitions="*,Auto"
                      IsVisible="{Binding ProcessorIsVisible}">
                    <Image Grid.Row="0"
                           Source="{Binding ProcessorImgSource}">
                        <Image.GestureRecognizers>
                            <DragGestureRecognizer CanDrag="True" />
                        </Image.GestureRecognizers>
                    </Image>

                    <Label Grid.Row="1"
                           Text="{Binding ProcessorLabel}"
                           TextColor="White"
                           FontSize="Medium"
                           BackgroundColor="Gray"
                           HorizontalTextAlignment="Center" />
                </Grid>
                <!--#endregion-->

            </StackLayout>
        </ScrollView>
    </Grid>


</ContentPage.Content>

视图模型 (.cs):

 [XamlCompilation(XamlCompilationoptions.Compile)]
 public partial class AssemblyPage : ContentPage
 {
      string caseSource;


      public AssemblyPage()
      {
           InitializeComponent();
      }

      int dragCount = 0;
      private void CaseDropZone_PropertyChanged(object sender,PropertyChangedEventArgs e)
      {
           if (e.PropertyName == "Source")
           {
                caseSource = imgCaseDropZone.source.ToString().Split(':').Last().Trim();

                if (string.IsNullOrEmpty(caseSource))
                {
                     return;
                }

                if (caseSource != "img_assembly_case.png")
                {
                     imgCaseDropZone.source = string.Empty;

                     lblDirections.Text = $"Drag Count: {++dragCount}";
                }
           }
      }

      private void TapGestureRecognizer_Tapped(object sender,EventArgs e)
      {
           Application.Current.MainPage.displayAlert("",$"{imgCaseDropZone.source}","OK");
      }
 }

GIF 中的当前构建演示:https://imgur.com/a/oLeM9DV(我无法直接链接 GIF,因为它太大)

解决方法

因为触发PropertyChanged事件时,拖放动作已经完成,图片已经自动设置到目标。

我们可以在使用 DragOver 事件将其拖到目标上方时立即做出判断。然后在拖放完成时使用 Drop 事件进行操作。

例如更改图片的代码(imgCaseDropZone):

 <Image x:Name="imgCaseDropZone"
        RelativeLayout.XConstraint="0"
        RelativeLayout.YConstraint="0"
        RelativeLayout.WidthConstraint="400"
        RelativeLayout.HeightConstraint="400"
        BackgroundColor="LightGray"
                       >
      <Image.GestureRecognizers>
            <DropGestureRecognizer AllowDrop="{Binding CaseIsVisible}"   DragOver="CaseDropZone_DragOver"  Drop="CaseDropZone_Drop"/>
            <TapGestureRecognizer Tapped="TapGestureRecognizer_Tapped" />
       </Image.GestureRecognizers>
 </Image>

在后面的代码中:

 private void CaseDropZone_DragOver(object sender,DragEventArgs e)
    {
        FileImageSource file = (FileImageSource)e.Data.Image;
        string name = file.File;
        if (name != "img_assembly_case.png")
        {
            e.Data.Image = string.Empty; // set the value string.Empty when drag it over the target,then it will fill the empty source to the image.
        }

    }

 private async void CaseDropZone_Drop(object sender,DropEventArgs e)
    {
        var ctx = (BindingContext as AssemblyViewModel);
        FileImageSource source = (FileImageSource)await e.Data.GetImageAsync();
        string name = source.File;
        if (name == "img_assembly_case.png")
        {
            ctx.CaseIsVisible = false;

            imgMotherboardDropZone.IsVisible = true;
        }
        else
        {
            Global.Score.PCAssembly -= 5;

            DisplayAlert($"Score: {Global.Score.PCAssembly}","The pre-requisite component for this part has not yet been placed.","OK");
        }
    }

其他图片都是这样修改的。

版权声明:本文内容由互联网用户自发贡献,该文观点与技术仅代表作者本人。本站仅提供信息存储空间服务,不拥有所有权,不承担相关法律责任。如发现本站有涉嫌侵权/违法违规的内容, 请发送邮件至 dio@foxmail.com 举报,一经查实,本站将立刻删除。

相关推荐


Selenium Web驱动程序和Java。元素在(x,y)点处不可单击。其他元素将获得点击?
Python-如何使用点“。” 访问字典成员?
Java 字符串是不可变的。到底是什么意思?
Java中的“ final”关键字如何工作?(我仍然可以修改对象。)
“loop:”在Java代码中。这是什么,为什么要编译?
java.lang.ClassNotFoundException:sun.jdbc.odbc.JdbcOdbcDriver发生异常。为什么?
这是用Java进行XML解析的最佳库。
Java的PriorityQueue的内置迭代器不会以任何特定顺序遍历数据结构。为什么?
如何在Java中聆听按键时移动图像。
Java“Program to an interface”。这是什么意思?
Java在半透明框架/面板/组件上重新绘画。
Java“ Class.forName()”和“ Class.forName()。newInstance()”之间有什么区别?
在此环境中不提供编译器。也许是在JRE而不是JDK上运行?
Java用相同的方法在一个类中实现两个接口。哪种接口方法被覆盖?
Java 什么是Runtime.getRuntime()。totalMemory()和freeMemory()?
java.library.path中的java.lang.UnsatisfiedLinkError否*****。dll
JavaFX“位置是必需的。” 即使在同一包装中
Java 导入两个具有相同名称的类。怎么处理?
Java 是否应该在HttpServletResponse.getOutputStream()/。getWriter()上调用.close()?
Java RegEx元字符(。)和普通点?