【问题标题】:Trying to close a ViewCell.ContextAction on button click in Xamarin尝试在 Xamarin 中单击按钮时关闭 ViewCell.ContextAction
【发布时间】:2020-01-07 02:54:07
【问题描述】:

目前它在列表视图中的设置是,如果用户在列表中的某个项目上向左滑动,它将显示用户可以按下的两个按钮(最喜欢的和已完成的,如上所示)。按钮做他们应该做的事情。唯一的问题是,我认为用户很难告诉他们按下的按钮实际上是有效的,所以我希望在他们按下按钮后我可以关闭 ContextAction。目前,他们可以让列表视图恢复正常或关闭该上下文操作的唯一方法是向左滑动。

我尝试将 x:Name 属性附加到单元格的 ContextActions 部分,以查看是否存在 IsVisible 或 Close 属性,但在后面的代码中找不到该名称。我还想知道是否有一种方法可以在我的 OnClick 事件中模仿向左滑动的动作。

知道如何让这样的事情发挥作用吗?我将在下面显示一些代码。 我认为这段代码的前 7 行是这里唯一重要的部分,但包含整个代码块以防万一。

  <ListView.ItemTemplate>
          <DataTemplate>
            <local:DabViewCell>
              <ViewCell.ContextActions x:Name="ContextAction">
                <MenuItem Clicked="OnListened" IsDestructive="true" Text="Completed" CommandParameter="{Binding .}"/>
                <MenuItem Clicked="OnFavorite" Text="Favorite" CommandParameter="{Binding .}"/>
              </ViewCell.ContextActions>
              <Grid Padding="10,10,10,10" RelativeLayout.WidthConstraint="{ConstraintExpression Type=RelativeToParent,Property=Width,Factor=1}" RelativeLayout.HeightConstraint="{ConstraintExpression Type=RelativeToParent,Property=Height,Factor=1}">
                <Grid.RowDefinitions>
                  <RowDefinition Height="Auto"/>
                  <RowDefinition Height="*"/>
                </Grid.RowDefinitions>
                <Grid.ColumnDefinitions>
                  <ColumnDefinition Width="Auto"/>
                  <ColumnDefinition Width="*"/>
                  <ColumnDefinition Width="Auto"/>
                </Grid.ColumnDefinitions>
                <BoxView Color="Transparent" IsVisible="{Binding listenedToVisible, Converter={StaticResource inverser}}" Grid.RowSpan="2" Grid.Column="0" WidthRequest="20" HeightRequest="20" VerticalOptions="Center"/>
                <Image Source="ic_done_listened_3x.png" IsVisible="{Binding listenedToVisible}" Grid.RowSpan="2" Grid.Column="0" WidthRequest="20" HeightRequest="20" VerticalOptions="Center"/>
                <StackLayout Orientation="Horizontal" Grid.Row="0" Grid.Column="1">
                  <local:DabLabel Text="{Binding title}" FontSize="Medium" HorizontalOptions="Start" Style="{StaticResource playerLabelStyle}" FontAttributes="Bold" IsTitle="true" LineBreakMode="TailTruncation"/>
                  <Image IsVisible="{Binding favoriteVisible}" Opacity=".5" HeightRequest="15" Aspect="AspectFit" Source="ic_star_white.png"/>
                  <Image IsVisible="{Binding hasJournalVisible}" Opacity=".5" HeightRequest="15" Aspect="AspectFit" Source="pencil_white.png"/>
                </StackLayout>
                <local:CircularProgressControl Progress="{Binding downloadProgress}" ProgressVisible="{Binding progressVisible}" DownloadVisible="{Binding downloadVisible}" HeightRequest="15" Grid.Column="2" Grid.RowSpan="2"/>
                <local:DabLabel Text="{Binding description}" FontSize="Micro" Grid.Row="1" Grid.Column="1" Style="{StaticResource secondaryLabelStyle}" LineBreakMode="TailTruncation"/>
              </Grid>
            </local:DabViewCell>
          </DataTemplate>
        </ListView.ItemTemplate>
      </ListView>                     

//更新:

我注意到,如果我在 OnFavorited 或 OnListened 方法中使用 await PlayerFeedAPI.UpdateEpisodeProperty() 注释掉该行,那么一切都会正确响应,但显然我仍然需要 UpdateEpisodeProperty 才能运行。我已经尝试使该方法不是异步思维,这可能会使它感到困惑,但还没有运气。它没有遇到我的任何异常.. UpdateEpisodeProperty 似乎运行良好。任何人都知道为什么这种方法会阻止我的上下文操作在点击时关闭?

public async void OnFavorite(object o, EventArgs e)
        {
            var mi = ((Xamarin.Forms.MenuItem)o);
            var model = ((EpisodeViewModel)mi.CommandParameter);
            var ep = model.Episode;
            await PlayerFeedAPI.UpdateEpisodeProperty((int)ep.id, null, !ep.is_favorite, null, null);
            await AuthenticationAPI.CreateNewActionLog((int)ep.id, "favorite", null, null, !ep.is_favorite);
            model.favoriteVisible = !ep.is_favorite;
        }
public static async Task UpdateEpisodeProperty(int episodeId, bool? isListened, bool? isFavorite, bool? hasJournal, int? playerPosition, bool RaiseEpisodeDataChanged = true)
        {
            try
            {
                //find the episode
                var episode = db.Table<dbEpisodes>().SingleOrDefault(x => x.id == episodeId);
                if (episode != null) //only update episodes we have in the database
                {
                    //listened
                    if (isListened != null)
                    {
                        episode.is_listened_to = (bool)isListened;
                    }
                    //favorite
                    if (isFavorite.HasValue)
                    {
                        episode.is_favorite = (bool)isFavorite;
                    }
                    //has journal
                    if (hasJournal.HasValue)
                    {
                        episode.has_journal = (bool)hasJournal;
                    }
                    //player position
                    if (playerPosition.HasValue)
                    {
                        if (GlobalResources.CurrentEpisodeId == episode.id)
                        {
                            if (!GlobalResources.playerPodcast.IsPlaying)
                            {
                                //update the active player (only if it is paused)
                                episode.stop_time = playerPosition.Value;
                                episode.remaining_time = (episode.Duration - episode.stop_time).ToString();
                                GlobalResources.playerPodcast.Seek(episode.stop_time);
                            } else
                            {
                                Debug.WriteLine("Skipping seek to new position since episode is playing...");
                            }
                        }
                        //
                    }
                    //save data to the database
                    db.Update(episode);
                }
                else
                {
                    //Store the record in the user-episode meta table for later use
                    dbUserEpisodeMeta meta = db.Table<dbUserEpisodeMeta>().SingleOrDefault(x => x.EpisodeId == episodeId);
                    if (meta == null)
                    {
                        meta = new dbUserEpisodeMeta();
                        meta.EpisodeId = episodeId; 
                    }
                    meta.CurrentPosition = playerPosition;
                    meta.HasJournal = hasJournal;
                    meta.IsFavorite = isFavorite;
                    meta.IsListenedTo = isListened;

                    db.InsertOrReplace(meta);
                    Debug.WriteLine($"Added episode {episodeId} to meta table for later use...");
                }

                //Notify listening pages that episode data has changed 
                if (RaiseEpisodeDataChanged)
                {
                    MessagingCenter.Send<string>("dabapp", "EpisodeDataChanged");
                }
            }
            catch (Exception e)
            {
                //Getting Locked exception on android 
                Debug.WriteLine($"Exception in PlayerFeedAPI.UpdateEpisodeProperty(): {e.Message}");
                DabData.ResetDatabases();
                db = DabData.database;
                adb = DabData.AsyncDatabase;
            }
        }

【问题讨论】:

  • 你的ios和xamarin.forms版本是什么?我无法重现问题,按下按钮后会自动恢复。可能是因为你的自定义单元格,你能显示你的自定义单元格代码吗?跨度>
  • 是的,我今天早上注意到,在我的平板电脑端,一切都按预期工作,但代码完全相同。我将使用自定义单元格代码更新我的问题。 xamarin.forms 版本是 2.5.1.527436。在多个 ios 版本上进行测试,但现在专注于 13.2。
  • 自定义单元格对我来说看起来不是很自定义
  • 我昨天也将 xamarin.forms 更新到最新版本,看看是否有帮助,但没有运气,所以我恢复了更改
  • 很奇怪,你有没有试过用viewcell代替customcell看看他是否还有这个问题?

标签: c# xamarin xamarin.ios


【解决方案1】:

我的 UpdateEpisodeProperty() 中的 MessagingCenter 让我离开了主线程,并阻止了 contextactions 菜单关闭 onClick。我为解决这个问题所做的就是在我的 UpdateEpisodeProperty() 中添加了一个可为空的属性,如果设置为 false,那么它将暂时跳过 MessagingCenter.Send()。我的代码中有一些小的 tweeks,但基本上如果我留在主线程上,那么 contextactions 会做出适当的响应。

仍然觉得奇怪的是,之前它是在 android 而不是 ios 上工作的。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2022-01-05
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2014-09-16
    相关资源
    最近更新 更多