【问题标题】:UWP Async MenuFlyout opening/openedUWP Async MenuFlyout 打开/打开
【发布时间】:2020-08-31 20:40:03
【问题描述】:

我需要以编程方式设置我的MenuFlyout。但是,我注意到将异步代码添加到我的函数后,MenuFlyout 不会显示其项目,除非我第二次右键单击该项目。如何以异步方式设置我的MenuFlyout

private async void MenuFlyout_Opened(object sender, object e)
{
    var flyout = sender as MenuFlyout;
    Music music = flyout.Target.DataContext as Music;
    if (await Helper.FileNotExist(music.Path))
    {
        if (Removable)
        {
            flyout.Items.Clear();
            flyout.Items.Add(MenuFlyoutHelper.GetRemovableMenuFlyoutItem(music, this));
        }
        else
        {
            Helper.ShowAddMusicResultNotification(music.Name);
        }
        return;
    }
    if (Removable) MenuFlyoutHelper.SetRemovableMusicMenu(sender, this);
    else MenuFlyoutHelper.SetMusicMenu(sender, this);
    if (AllowReorder)
    {
        var item = new MenuFlyoutItem()
        {
            Text = Helper.Localize("Move To Top"),
            Icon = new SymbolIcon(Symbol.Upload)
        };
        item.Click += (s, args) =>
        {
            MediaHelper.MoveMusic(music.Index, 0);
        };
        flyout.Items.Add(item);
    }
}

一种方法是避免在此类函数中使用异步代码,并检查项目的Click 事件中是否存在文件。但是我的东西太多了。我认为这是个坏主意。

这段代码可以正常工作:

private void OpenMusicMenuFlyout(object sender, object e)
{
    if (Removable) MenuFlyoutHelper.SetRemovableMusicMenu(sender, this);
    else MenuFlyoutHelper.SetMusicMenu(sender, this);
    if (AllowReorder)
    {
        var flyout = sender as MenuFlyout;
        var item = new MenuFlyoutItem()
        {
            Text = Helper.Localize("Move To Top"),
            Icon = new SymbolIcon(Symbol.Upload)
        };
        item.Click += (s, args) =>
        {
            Music music = (s as MenuFlyoutItem).DataContext as Music;
            MediaHelper.MoveMusic(music.Index, 0);
        };
        flyout.Items.Add(item);
    }
}

使用Dispatcher.RunAsync 编码:

private async void OpenMusicMenuFlyout(object sender, object e)
{
    var flyout = sender as MenuFlyout;
    Music music = flyout.Target.DataContext as Music;
    if (await Helper.FileNotExist(music.Path))
    {
        if (Removable)
        {
            flyout.Items.Clear();
            flyout.Items.Add(MenuFlyoutHelper.GetRemovableMenuFlyoutItem(music, this));
        }
        else
        {
            Helper.ShowAddMusicResultNotification(music.Name);
        }
        return;
    }
    await Dispatcher.RunAsync(Windows.UI.Core.CoreDispatcherPriority.High, () =>
    {

        if (Removable) MenuFlyoutHelper.SetRemovableMusicMenu(sender, this);
        else MenuFlyoutHelper.SetMusicMenu(sender, this);
        if (AllowReorder)
        {
            var item = new MenuFlyoutItem()
            {
                Text = Helper.Localize("Move To Top"),
                Icon = new SymbolIcon(Symbol.Upload)
            };
            item.Click += (s, args) =>
            {
                MediaHelper.MoveMusic(music.Index, 0);
            };
            flyout.Items.Add(item);
        }
    });
}

【问题讨论】:

  • 你可以尝试通过调用 Dispatcher.Run() 方法在 UI 线程中添加MenuFlyoutItem 吗?
  • @NicoZhu-MSFT 这不起作用。
  • 你的意思是async void MenuFlyout_Opened 导致浮出控件不显示?
  • 其实第一次右键点击后会显示MenuFlyoutItem。但是MenuFlyout第一次出现时,它是空的。 @NicoZhu-MSFT
  • 我发现你在MenuFlyout_Opened 方法中调用了异步方法,你可以尝试用同步调用它们吗?

标签: c# uwp win-universal-app


【解决方案1】:

很好的问题,为了测试,如果我们在上面的OpenMusicMenuFlyout事件处理程序中调用异步函数,MenuFlyout添加操作将被中断,UI渲染将被取消。对于上述情况,更好的方法是将Flyout 设为ContextFlyout 内容,然后使用ListView 替换MenuFlyout。更多信息请查看以下内容。

<SwipeControl>
    <SwipeControl.ContextFlyout>
        <Flyout Opening="OpenMusicMenuFlyout">
            <ListView>
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <TextBlock Text="{Binding}"/>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Flyout>
    </SwipeControl.ContextFlyout>
</SwipeControl>

代码背后

private async void OpenMusicMenuFlyout(object sender, object e)
{
    var items = new ObservableCollection<string>() { "One", "Two", "Three" };
    var flyout = sender as Flyout;
    var menu =  flyout.Content as ItemsControl;
    await TestMetod();
    menu.ItemsSource = items;
}

【讨论】:

    猜你喜欢
    • 2019-03-16
    • 1970-01-01
    • 1970-01-01
    • 2016-09-26
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多