WinRT 调用 Flyout.ShowAt() 异步
WinRT call Flyout.ShowAt() async
我正在构建自己的带有列表选择的 Flyout
控件,以便在 Windows Phone 以及 Windows 桌面上使用它。与 ListPickerFlyout class, the Flyout 不同,class 没有异步方法来显示弹出窗口。
如何在弹出窗口关闭后异步调用 ShowAt
方法并 return 返回所选值?
解决方案:
异步行为可以通过 TaskCompletionSource<T>
实现(感谢 AwaitableUI libary)。仍然困扰我的是我必须在构造函数中手动创建 ListView。如果我可以改用 XAML 并只分配一个模板就好了,但我没有找到可行的方法。
public class ListPickerFlyout<T> : Flyout where T : class
{
private event EventHandler<object> ItemPicked;
public ListPickerFlyout(IEnumerable<T> items)
{
Placement = FlyoutPlacementMode.Full;
Opening += OnOpening;
Closed += OnClosed;
var listView = new ListView();
listView.SelectionMode = ListViewSelectionMode.None;
listView.IsItemClickEnabled = true;
listView.ItemClick += OnItemClick;
listView.DisplayMemberPath = "Name";
listView.SetBinding(ListView.ItemsSourceProperty, new Binding { Source = items });
Content = listView;
}
public async Task<T> ShowAsync()
{
this.ShowAt(Window.Current.Content as Frame);
var tcs = new TaskCompletionSource<T>();
EventHandler<object> eventHandler = null;
eventHandler = (s, e) =>
{
this.Closed -= eventHandler;
this.ItemPicked -= eventHandler;
tcs.SetResult(e as T);
};
this.Closed += eventHandler;
this.ItemPicked += eventHandler;
return await tcs.Task;
}
private void OnItemClick(object sender, ItemClickEventArgs e)
{
var selectedItem = e.ClickedItem as T;
var eventHandler = ItemPicked;
if (eventHandler != null)
eventHandler(this, selectedItem);
this.Hide();
}
private void OnOpening(object sender, object e)
{
var frame = Window.Current.Content as Frame;
var page = frame.Content as Page;
if (page != null)
page.BottomAppBar.Visibility = Visibility.Collapsed;
}
private void OnClosed(object sender, object e)
{
var frame = Window.Current.Content as Frame;
var page = frame.Content as Page;
if (page != null)
page.BottomAppBar.Visibility = Visibility.Visible;
}
}
与后端工作不同,ShowAt 是一种 UI 交互。 PickerFlyout class 有 ShowAtAsync 方法,但不用于 "wait" 选择器结果。
在XAML开发中,async方法通常是为了避免UI阻塞。
而对于用户交互部分,我推荐使用事件驱动模式。
在这种情况下,我建议在 "Closed" 事件处理程序中检索 select 项。
WinRT XAML 工具包具有可等待 UI 的概念,这使得等待许多通常不应用可等待逻辑的 UI 元素成为可能。我还没有在 Flyout 上尝试过,但它可能会起作用。
你可以找到它here
我正在构建自己的带有列表选择的 Flyout
控件,以便在 Windows Phone 以及 Windows 桌面上使用它。与 ListPickerFlyout class, the Flyout 不同,class 没有异步方法来显示弹出窗口。
如何在弹出窗口关闭后异步调用 ShowAt
方法并 return 返回所选值?
解决方案:
异步行为可以通过 TaskCompletionSource<T>
实现(感谢 AwaitableUI libary)。仍然困扰我的是我必须在构造函数中手动创建 ListView。如果我可以改用 XAML 并只分配一个模板就好了,但我没有找到可行的方法。
public class ListPickerFlyout<T> : Flyout where T : class
{
private event EventHandler<object> ItemPicked;
public ListPickerFlyout(IEnumerable<T> items)
{
Placement = FlyoutPlacementMode.Full;
Opening += OnOpening;
Closed += OnClosed;
var listView = new ListView();
listView.SelectionMode = ListViewSelectionMode.None;
listView.IsItemClickEnabled = true;
listView.ItemClick += OnItemClick;
listView.DisplayMemberPath = "Name";
listView.SetBinding(ListView.ItemsSourceProperty, new Binding { Source = items });
Content = listView;
}
public async Task<T> ShowAsync()
{
this.ShowAt(Window.Current.Content as Frame);
var tcs = new TaskCompletionSource<T>();
EventHandler<object> eventHandler = null;
eventHandler = (s, e) =>
{
this.Closed -= eventHandler;
this.ItemPicked -= eventHandler;
tcs.SetResult(e as T);
};
this.Closed += eventHandler;
this.ItemPicked += eventHandler;
return await tcs.Task;
}
private void OnItemClick(object sender, ItemClickEventArgs e)
{
var selectedItem = e.ClickedItem as T;
var eventHandler = ItemPicked;
if (eventHandler != null)
eventHandler(this, selectedItem);
this.Hide();
}
private void OnOpening(object sender, object e)
{
var frame = Window.Current.Content as Frame;
var page = frame.Content as Page;
if (page != null)
page.BottomAppBar.Visibility = Visibility.Collapsed;
}
private void OnClosed(object sender, object e)
{
var frame = Window.Current.Content as Frame;
var page = frame.Content as Page;
if (page != null)
page.BottomAppBar.Visibility = Visibility.Visible;
}
}
与后端工作不同,ShowAt 是一种 UI 交互。 PickerFlyout class 有 ShowAtAsync 方法,但不用于 "wait" 选择器结果。
在XAML开发中,async方法通常是为了避免UI阻塞。 而对于用户交互部分,我推荐使用事件驱动模式。
在这种情况下,我建议在 "Closed" 事件处理程序中检索 select 项。
WinRT XAML 工具包具有可等待 UI 的概念,这使得等待许多通常不应用可等待逻辑的 UI 元素成为可能。我还没有在 Flyout 上尝试过,但它可能会起作用。
你可以找到它here