2013-06-27 49 views
2

本質上我需要Form.ShowDialog()提供的同樣的東西,但是用戶控件。用戶操作後usercontrol的返回值

在一個winform中,我加載一個UserControl,它應該允許用戶從列表中選擇一個項目,並將其返回給調用者。

例如:

var item = myUserControl.SelectItem(); 

顯然,從控制的方法恢復是很簡單的。但是,如何才能讓用戶等到用戶使用控件執行所需操作?

我可以訂閱控件的事件,但此路徑並不理想。

簡單地說,我想要一個UserControl的方法在用戶點擊一個特定的按鈕後返回。

+0

嗯,你的設計到底如何?例如。像@ pm_2這樣的表單彈出窗口會出現什麼問題?顯示用戶控件時應該禁用哪些內容? –

+0

我假設你要 阻止UI風格,看起來很棒。在網上你可以找到jscript的例子。但我們曾經爲我們的前端窗口做過 – qwr

+1

這是一款類似於手機的設計。該應用程序有多個頁面(構建爲UserControls)。其中一個頁面可用作選擇某些值的小部件。用戶點擊一個按鈕以確認選擇。在UserControl中選擇該值後,父表單中的代碼應該處理它。所以基本上這個表單加載一個臨時的UserControl來允許用戶選擇一個值。 – SharpAffair

回答

0

將它嵌入到窗體中並以模態方式調用窗體(ShowDialog)?

+0

我需要主窗體內的控件。我的想法是有一個單一表格的應用程序,但需要加載多個不同的頁面。 – SharpAffair

+0

然後,您別無選擇,只能在用戶控件上啓用/顯示其他控件。 –

3

簡而言之,UserControl實際上只是一個自定義控件,就像在WinFrom上放置一個TextBoxListBox一樣,您將UserControl放在窗體上。

像對待任何其他控件一樣對待您的UserControl,如TextBoxListBox

所以,就像你從一個TextBox通過TextBox.TextSelectedValueSelectedItemListBox的價值,你會叫您的用戶控件的方法返回的SelectedItem。

通常,單擊確定按鈕或窗體關閉時,在代碼中時,您會通過窗體的每個控件獲取其值。據推測,你會做一些驗證,以確保輸入正確的值。

因此,當您的表單被接受時,您將調用您的UserControl的方法來獲取所選項目。您不必訂閱活動即可等待發生。再次,就像對待正常的ListBox一樣對待它。

編輯:

知道現在更多關於您的問題,這個性質就是我的回答:

假設你有一個用戶控件,看起來像這樣:

SelectFromListUserControl

在你後面的代碼將不得不設置一個事件來監視何時在UserControl中單擊了OK按鈕。此事件也將通知用戶什麼樣的選擇是,在你的列表中選擇用戶:

public partial class SelectFromListUserControl : UserControl 
{ 
    public class SelectedItemEventArgs : EventArgs 
    { 
     public string SelectedChoice { get; set; } 
    } 

    public event EventHandler<SelectedItemEventArgs> ItemHasBeenSelected; 

    public SelectFromListUserControl() 
    { 
     InitializeComponent(); 
    } 

    private void btnOK_Click(object sender, EventArgs e) 
    { 
     var handler = ItemHasBeenSelected; 
     if (handler != null) 
     { 
      handler(this, new SelectedItemEventArgs 
       { SelectedChoice = listBox1.SelectedItem.ToString() }); 
     } 
    } 
} 

在主窗體,你將有代碼圖案類似於以下。

  1. 應該有一個例程來創建或使這個特殊的用戶控件可見。
  2. 它將鉤住用戶控件中的事件,以便通知主窗體。
  3. 它會繪製用戶控件。
  4. 事件處理程序將檢索用戶控件中選定的值,然後清除用戶控件和/或調出其他用戶控件。

    private void ShowSelectFromListWidget() 
    { 
        var uc = new SelectFromListUserControl(); 
        uc.ItemHasBeenSelected += uc_ItemHasBeenSelected; 
    
        MakeUserControlPrimaryWindow(uc); 
    } 
    
    void uc_ItemHasBeenSelected(object sender, 
            SelectFromListUserControl.SelectedItemEventArgs e) 
    { 
        var value = e.SelectedChoice; 
    
        ClosePrimaryUserControl(); 
    } 
    
    private void MakeUserControlPrimaryWindow(UserControl uc) 
    { 
        // my example just puts in in a panel, but for you 
        // put your special code here to handle your user control management 
        panel1.Controls.Add(uc); 
    } 
    
    private void ClosePrimaryUserControl() 
    { 
        // put your special code here to handle your user control management 
        panel1.Controls.Clear(); 
    } 
    
+1

它看起來像OP希望用戶只能與其UserControl進行交互,出於某種原因,修改UserControl之外的任何信息/數據可能會導致其應用程序不正常工作。所以他希望一切順利。在某些情況下,您的方法是可行的,但這不是OP的情況。 –

+0

@KingKing,我想我現在看到OP在嘗試存檔什麼,並添加了一個模式的代碼示例,我認爲他可以按照他的要求來實現他想要的內容。 –

0

但我怎麼可以讓它等到用戶執行與控制所需的行動?

問題是關於如何等待用戶選擇項目並單擊確定按鈕,而不會阻止整個用戶界面。

答案很簡單:異步/等待功能。

private readonly SelectCompletionSource as new TaskCompletionSource(of ResultType) 

public async function SelectItemAsync() as ResultType 

    me.Visible = true 

    return await SelectComplectionSource.Task 
end function 

public function OK() as boolean 

    me.Visible = false 

    dim Result = me.SelectedItem 

    SelectComplectionSource. 
     SetResult(Result) 
end function 

爲了得到一個Item一個調用

dim Item = await UserControl.SelectItemAsync 

UserControl被示出給用戶而不阻塞用戶界面。選擇任務已啓動但暫停,直到結果準備就緒。

通過點擊確定按鈕,用戶調用OK函數查詢選定的項目,並使選擇任務進入完成狀態。