2010-05-14 63 views
9

如何將焦點設置爲TextBox而不指定該名稱TextBox?目前,我做了以下MVVM Focus To Textbox

<Window FocusManager.FocusedElement="{Binding ElementName=Username}"> 
    <Grid> 
     <TextBox Text="{Binding Username}" Name="Username" />    
    </Grid> 
</Window> 

是否有這樣做而沒有指定名稱爲TextBox的任何方式。因爲我認爲MVVM具有Name元素通常意味着糟糕的設計?

+0

我不認爲有一個元素的名稱本身就是不好的設計,但給元素一個名稱,以便您可以在代碼隱藏中引用它,應該避免。我沒有看到上面的觀點有什麼不妥。 – lesscode 2010-05-14 14:50:06

+0

考慮是否要使用觸發器在視圖中執行任何特殊操作(動畫和其他狀態更改) - 名稱對於這些操作非常重要。 – Gusdor 2011-07-26 12:36:28

回答

2

我在a similar problem的回答中記錄了一個「純MVVM」的方法。該解決方案涉及使用附加屬性以及將視圖模型中的界面命令傳遞迴視圖的框架。

+0

http://geekswithblogs.net/HouseOfBilz/archive/2009/08/27/adventures-in-mvvm-ndash-binding-commands-to-any-event.aspx – Agies 2010-05-21 02:03:40

20

因爲我相信MVVM有一個Name元素通常意味着設計不好?

不,它不是。

MVVM模式不是關於從代碼隱藏文件中消除所有代碼。

這是關於分離問題和提高可測試性。 查看相關代碼,如焦點處理應保留在視圖的代碼隱藏文件中。但是在View的代碼隱藏文件中看到應用程序邏輯或數據庫連接管理會很糟糕。

MVVM示例代碼隱藏文件中的代碼沒有違反MVVM模式可以在WPF Application Framework (WAF)項目中找到。

+7

+1 ** MVVM模式是不是消除代碼隱藏文件中的所有代碼都很好 – ktutnik 2012-07-10 03:22:15

6

簡單的方法是在UserControl_Load事件將焦點設置

 this.txtBox.Focus(); 
     txtBox.Focusable = true; 
     Keyboard.Focus(txtBox); 

MVVM並不意味着你不能把代碼隱藏文件中的代碼。事實上,不要讓任何模式限制你找到最好的編碼方式。

0

實際上,我發現布爾附加屬性解決方案有點骯髒和笨拙的方式,你必須找到一個扭曲,以確保下一組視圖模型屬性將真正引發附加屬性更改事件。

一個簡單和更優雅的解決方案是綁定你的行爲屬性類型,你可以確保下一個值將永遠不同於前一個,從而確保你的附屬屬性改變事件會每次提升。

想到的最簡單的類型是int。然後將溶液的通常的組合:

行爲:

class TextBoxFocusBehavior 
{ 
    public static int GetKeepFocus(DependencyObject obj) 
    { 
     return (int)obj.GetValue(KeepFocusProperty); 
    } 

    public static void SetKeepFocus(DependencyObject obj, int value) 
    { 
     obj.SetValue(KeepFocusProperty, value); 
    } 

    // Using a DependencyProperty as the backing store for KeepFocus. This enables animation, styling, binding, etc... 
    public static readonly DependencyProperty KeepFocusProperty = 
     DependencyProperty.RegisterAttached("KeepFocus", typeof(int), typeof(TextBoxFocusBehavior), new UIPropertyMetadata(0, OnKeepFocusChanged)); 

    private static void OnKeepFocusChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     TextBox t = d as TextBox; 
     if (t != null) 
     { 
      t.Focus(); 
     } 
    } 
} 

視圖模型屬性:

public int InputFocus 
    { 
     get { return _inputFocus; } 
     private set 
     { 
      _inputFocus = value; 
      Notify(Npcea.InputFocus); 
     } 
    } 

使用該附加的行爲的:

<TextBox v:TextBoxFocusBehavior.KeepFocus="{Binding InputFocus}"/> 

而最終使用VM中的財產:

public void YouMethod() 
    { 
     //some code logic 
     InputFocus++;//<= the textbox focus 
    } 

一些非常壞的思想精神可以說,這種邏輯被綁定到INT32大小限制。那麼......我現在就選擇忽略它們;-)

0

因爲我相信MVVM有一個Name元素通常意味着糟糕的設計?

不,不是。

根據微軟MVP的命名控件不僅是WPF不好的做法,它是一個相當大的性能打擊。只是想沿着智慧

有些話我與肖恩·杜同意關於不讓任何模式完全限制你通過了,我覺得應該儘量避免性能下降。