【发布时间】: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