在方法中间显示列表视图但等到SelectionChanged事件在方法继续之前触发

时间:2017-03-24 04:11:05

标签: c# .net listview windows-10-universal

C#中的Windows UWP应用程序。我有一个检查条件的方法,根据条件,它可能需要向用户显示列表视图,以便他们可以从列表中选择一个项目。在我可能显示需要运行的列表视图之后,我在该方法中有更多代码。但是,因为listview显示并且我必须等待SelectionChanged事件处理程序触发,所以我无法弄清楚如何在该行上暂停调用方法,直到为SelectionChanged完成事件处理程序。我还没有编写代码,所以这里有一些pseduo代码来说明:

private void LookupEmployee(string searchCriteria)
{
     List<string> matches = GetEmployeeNameMatchesFromCriteria(searchCriteria);

     if(matches.Count == null || matches.Count == 0)
     {
         //No matches found, warn user
         return;
     }
     if(matches.Count == 1)
     {
         //We are good, we have just one match which is desirable.
     }
     if(matches.Count > 1)
     {
         //This means we have more than one match and we need to popup list view to have user select one
         ShowListView(matches);
     }

     //Process Employee data here.
}

我知道一个选项是&#34;菊花链&#34;通过将员工数据的最终处理分解为另一个方法并从列表视图的SelectionChanged的事件处理程序中调用该方法来调用。但是,这有两个问题。首先,如果我只有一个匹配,那么无论如何我都不会显示列表视图或获取SelectionChanged。其次,如果我在方法的最后使用方法的开头有一堆变量和其他东西,我不想(也不知道如何)通过所有这些并且在我需要展示它的事件中从事件处理程序返回。

我想我在寻找的方式是如何处理MessageDialog。

 var md = new MessageDialog("My Message");

 md.Commands.Add(new UICommand("Okay")
 {

 });

 var result = await md.ShowAsync();

 if (result.Label == "Okay")
 {
     DoStuff;
 }

使用它的地方会在线上等待:

await md.ShowAsync();

在用户点击按钮之前,该方法可以从那里继续。

我想我正在寻找类似的东西,在我需要显示列表视图的情况下,我可以按住该方法,直到用户选择和项目并抓住所选项目。

思想?

谢谢!

1 个答案:

答案 0 :(得分:0)

好的,我想我找到了我要找的东西所以我想发布代码。这类似于过去模态窗口的工作方式。基本上,您可以使用ContentDialog,它允许您“包装”您想要的任何控件。在我的情况下,我想显示一个ListView,所以我将它包装在ContentDialog中。这就是我所拥有的:

  1. 首先我们可以进行测试,根据测试,我们可以根据需要创建ContentDialog / ListView。如果我们确实创建了ContentDialog,我们也可以设置Display参数,使其符合我们想要的方式。

    private async void checkProductMatches()
    {
        var selectedItem = string.Empty;
    
        //Check our results from DB.
        if (productResults.Count == 0)
        {
            //This means we didn't find any matches, show message dialog
        }
        if (productResults.Count == 1)
        {
            //We found one match, this is ideal. Continue processing.
            selectedItem = productResults.FirstOrDefault().Name;
        }
        if (productResults.Count > 1)
        {
            //Multiple matches, need to show ListView so they can select one.
            var myList = new ListView
            {
                ItemTemplate = Create(),
                ItemsSource =
                    productResults,
                    HorizontalAlignment = HorizontalAlignment.Stretch,
                    VerticalAlignment = VerticalAlignment.Stretch
            };
    
            var bounds = Window.Current.Bounds;
            var height = bounds.Height;
            var scroll = new ScrollViewer() { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch, Height = height - 100 };
    
            var grid = new StackPanel();
            grid.Children.Add(myList);
            scroll.Content = grid;
            var dialog = new ContentDialog { Title = "Title", Content = scroll };
    
  2. 现在,我们连接ListView SelectionChanged事件的事件处理程序,并在此事件引发时抓取selectedItem。

            myList.SelectionChanged += delegate (object o, SelectionChangedEventArgs args)
            {
                if (args.AddedItems.Count > 0)
                {
                    MyProducts selection = args.AddedItems[0] as MyProducts;
                    if (selection != null)
                    {
                        selectedItem = selection.Name;
                    }
                }
                dialog.Hide();
            };
    
  3. 最后,我们等待ContentDialog的显示。

            var s = await dialog.ShowAsync();
    
  4. 这样做,如果我们有一个项目,则无需弹出内容对话框。因此,我们可以将一个结果分配给selectedItem变量并继续。但是,如果我们有多个匹配项,我们希望显示一个列表供用户选择一个项目。在这种情况下,我们创建ContentDialog,ListView和显示参数。它们的关键是在我们调用显示对话框之前连接事件处理程序并在事件处理程序内部,我们确保取消或关闭对话框。然后我们打电话等待对话显示。这将在对话框显示时暂停该行的执行。一旦用户选择了一个项目,事件处理程序将引发,获取所选项目,然后关闭对话框,然后允许该方法从等待的行继续执行。

    以下是完整的方法:

        private async void checkProductMatches()
        {
            var selectedItem = string.Empty;
    
            //Check our results from DB.
            if (productResults.Count == 0)
            {
                //This means we didn't find any matches, show message dialog
            }
            if (productResults.Count == 1)
            {
                //We found one match, this is ideal. Continue processing.
                selectedItem = productResults.FirstOrDefault().Name;
            }
            if (productResults.Count > 1)
            {
                //Multiple matches, need to show ListView so they can select one.
                var myList = new ListView
                {
                    ItemTemplate = Create(),
                    ItemsSource =
                        productResults,
                        HorizontalAlignment = HorizontalAlignment.Stretch,
                        VerticalAlignment = VerticalAlignment.Stretch
                };
    
                var bounds = Window.Current.Bounds;
                var height = bounds.Height;
                var scroll = new ScrollViewer() { HorizontalAlignment = HorizontalAlignment.Stretch, VerticalAlignment = VerticalAlignment.Stretch, Height = height - 100 };
    
                var grid = new StackPanel();
                grid.Children.Add(myList);
                scroll.Content = grid;
                var dialog = new ContentDialog { Title = "Title", Content = scroll };
    
                myList.SelectionChanged += delegate (object o, SelectionChangedEventArgs args)
                {
                    if (args.AddedItems.Count > 0)
                    {
                        MyProducts selection = args.AddedItems[0] as MyProducts;
                        if (selection != null)
                        {
                            selectedItem = selection.Name;
                        }
                    }
                    dialog.Hide();
                };
    
                var s = await dialog.ShowAsync();
            }
    
            //Test furter execution. Ideally, selected item will either be the one record or we will 
            //get here after the list view allows user to select one.
            var stringTest = string.Format("Selected Item: {0}", selectedItem);
        }
    

    希望这有助于某人。