尝试在 Xamarin 中单击按钮时关闭 ViewCell.ContextAction [英] Trying to close a ViewCell.ContextAction on button click in Xamarin

查看:31
本文介绍了尝试在 Xamarin 中单击按钮时关闭 ViewCell.ContextAction的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

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

Currently its set in the listview that if the user swipes left on an item in the list it will then bring up two buttons (favorite and completed, shown above) the user could press. The buttons do what they are supposed to do. The only thing is that I think it is hard for the users to tell their button pressed actually worked so I was hoping I could close the ContextAction after they press the button. Currently, the only way they can get the listview to go back to normal, or close that Context Action is to swipe left.

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

I tried attaching a x:Name property to the ContextActions part of the cell to see if there was an IsVisible or Close property but that name wasn't being found in my code behind. I'm also wondering if there is a way I could mimic a swipe left action in my OnClick events.

知道如何让这样的东西工作吗?我将在下面展示一些代码.我认为这段代码的前 7 行是唯一在这里很重要的代码,但为了以防万一,它包含了整个代码块.

Any idea how I could get something like this to work? I'll show some code below. First 7 lines of this code I believe is the only this that is important here but included the whole block just in case.

  <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 似乎运行良好.任何人都知道为什么这种方法会阻止我的上下文操作在点击时关闭?

I've noticed that if I comment out the line with await PlayerFeedAPI.UpdateEpisodeProperty() in either of those OnFavorited or OnListened methods then everything responds properly but obviously I still need UpdateEpisodeProperty to run. I've tried making that method not async thinking that could be confusing it but no luck yet. It's not hitting any of my exceptions.. UpdateEpisodeProperty seems to be running fine. Anything pop out to anybody as to why this method is keeping my contextactions from closing on click?

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;
            }
        }

推荐答案

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

MessagingCenter within my UpdateEpisodeProperty() got me off the main thread and kept the contextactions menu from closing onClick. What I did to fix this was added a nullable property to my UpdateEpisodeProperty() and if set to false then it would skip the MessagingCenter.Send() for the moment. There were some minor tweeks in my code but basically if I stayed on the main thread then contextactions responded appropriately.

在它用于 android 而不是 ios 之前,仍然认为这很奇怪.

Still think it's odd that before it was working on android and not ios.

这篇关于尝试在 Xamarin 中单击按钮时关闭 ViewCell.ContextAction的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆