2017-03-24 46 views
0

在C#中的Windows應用程序UWP。我有一個方法檢查一個條件,並根據條件,它可能需要向用戶顯示一個列表視圖,以便他們可以從列表中選擇一個項目。在我可能顯示需要運行的列表視圖之後,我在方法中有更多的代碼。然而,因爲listview顯示,我必須等待SelectionChanged事件處理程序觸發,我不知道如何暫停該行上的調用方法,直到完成SelectionChanged的事件處理程序。我沒有做編寫的代碼還,所以這裏是一些pseduo代碼來說明:顯示列表視圖但等到方法之前SelectionChanged事件觸發繼續

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

我知道有一個選項是「菊花鏈」,打破了員工數據的最終處理,以另一種方法和呼叫調用即來自ListView的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; 
} 

凡使用此等待上線:

等待md.ShowAsync();

直到用戶點擊該按鈕時,在該點處該方法可繼續從那裏。

我想我正在尋找類似的東西,我可以堅持在方法的行中,我需要顯示列表視圖,直到用戶選擇和項目並抓取被選中的項目的行。

想法?

謝謝!

+0

也許可以做...與await Task.Delay(100);並檢查用戶是否按下確認按鈕? – Niewidzialny

回答

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(); 
    

這是什麼會做的是,如果我們有一個項目,就沒有必要彈出對話框的內容。所以,我們可以將一個結果分配給我們的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); 
    } 

希望這可以幫助別人。

相關問題