2011-04-06 62 views
42

我有一個頁面,其中包含一些用於數據輸入的文本框。文本框的綁定設置爲TwoWay。如果文本框失去焦點,我的視圖模型中的數據纔會更新。如果我點擊一個按鈕(如保存),並且文本框仍具有焦點,則在保存事件的視圖模型中,文本框中的更改不會更改。TextBox Binding TwoWay不會更新,直到焦點丟失WP7

有沒有辦法讓綁定保存文本框的值失去焦點之前?或者我需要在保存事件中做些什麼?

+0

上WP8同樣的問題,答案@StefanWick解決對我來說。 – 2013-04-08 13:43:33

+1

在這裏您可以找到更新TextChanged事件綁定的工作解決方案:http://stackoverflow.com/a/4833196/928955 – breigo 2012-09-10 20:05:39

回答

7

您可以使用Prism Library for WP7中的UpdateTextBindingOnPropertyChanged行爲在文本更改而不是丟失焦點時更新邊界值。

+3

我已經在使用MVVM Light,並且不希望僅爲此包含Prism。 :( – 2011-04-06 17:15:32

+0

那麼,源代碼也可用,所以你可以只包含一個文件;) – 2011-04-06 17:37:29

+0

是的,這就是我現在看到的。我不知道WP7的輕量級Prism實際上是多少。我可能不得不查找棱鏡和MVVM Light之間的區別。棱鏡似乎有一些額外的東西,我需要使用。 – 2011-04-06 17:44:42

16

下載Charles Petzold的免費書籍Programming Windows Phone 7。他在第387頁談到如何做到這一點。

基本上,將UpdateSourceTrigger屬性Binding設置爲Explicit。然後,在TextBoxTextChanged回調中,更新綁定源。

1

我還沒有嘗試過@Praetorian的答案,所以如果工作的很好,那麼做 - 否則,同時使用KeyUp和TextChanged事件來更新綁定源。

6

我正在@Praetorian的相反方向。

您的TextBox的默認值UpdateSourceTrigger的值爲LostFocus。這意味着只有當它失去焦點時纔會將值推送到ViewModel屬性。

您可以將UpdateSourceTrigger設置的PropertyChanged:

<TextBox UpdateSourceTrigger="PropertyChanged" Text="{Binding TextViewModelProperty}" /> 

http://msdn.microsoft.com/en-us/library/system.windows.data.binding.updatesourcetrigger.aspx

其中UpdateSourceTrigger值。 默認值爲Default,它將返回 目標依賴項屬性的默認UpdateSourceTrigger值 。 但是,大多數 依賴項屬性的默認值爲 PropertyChanged,而文本 屬性的默認值爲 LostFocus。

請記住,這意味着,任何通過更新此屬性爲觸發將更加頻繁地發生(基本上與每一個按鍵,而不是一個單一的「沖洗」當TextBox失去焦點)。

希望有幫助!

+3

Silverlight不支持'UpdateSourceTrigger'的'PropertyChanged'值。您已鏈接WPF主題,WP7主題不適用WP7主題。 – 2011-04-06 20:18:33

+0

糟糕,我是WPF的傢伙,所以我總是忘記了!抱歉! – rrhartjr 2011-04-07 13:49:03

+4

將Text屬性設置爲Text =「{Binding TextViewModelProperty,Mode = TwoWay,UpdateSourceTrigger = PropertyChanged}」爲我工作(我正在使用SL5)。 – 2013-09-03 11:36:58

55

我假設你的保存按鈕是一個ApplicationBarButton(不是普通的按鈕)。對於普通的按鈕,它會正常工作,因爲它們需要關注,因此數據綁定將啓動。

對於手機上的ApplicationBarButtons,它有點不同,因爲它們不會將焦點從客戶端應用程序中移除。爲了確保在客戶按下保存按鈕時在數據綁定踢,你可以在你的處理程序中添加以下代碼:

object focusObj = FocusManager.GetFocusedElement(); 
if (focusObj != null && focusObj is TextBox) 
{ 
    var binding = (focusObj as TextBox).GetBindingExpression(TextBox.TextProperty); 
    binding.UpdateSource(); 
} 
+3

謝謝。很好理解爲什麼。 – 2011-04-06 21:41:15

+0

謝謝你。每次更新文本屬性時,我們都會自動保存數據結構,並且每次擊鍵都會發生這種情況,這種感覺並不合適。 – dythim 2013-04-23 04:52:38

+0

感謝它幫助我,因爲我不使用MVVM光。 – NoobDeveloper 2013-05-18 17:05:19

6

這裏有一個快速訪問的答案德里克建議的微軟解決方案。而不是下載,並通過所有的棱鏡的東西篩選,只是這個類複製到你的項目,然後按照步驟之後將其激活:

UpdateBindingOnPropertyChangedBehviour.cs

using System; 
using System.Windows.Controls; 
using System.Windows.Data; 
using System.Windows.Interactivity; 

namespace MyCompany.MyProduct 
{ 
    /// <summary> 
    /// Custom behavior that updates the source of a binding on a text box as the text changes. 
    /// </summary> 
    public class UpdateTextBindingOnPropertyChanged : Behavior<TextBox> 
    { 
     /// <summary> 
     /// Binding expression this behavior is attached to. 
     /// </summary> 
     private BindingExpression _expression; 

     /// <summary> 
     /// Called after the behavior is attached to an AssociatedObject. 
     /// </summary> 
     /// <remarks> 
     /// Override this to hook up functionality to the AssociatedObject. 
     /// </remarks> 
     protected override void OnAttached() 
     { 
      base.OnAttached(); 

      // Hook events to change behavior 
      _expression = AssociatedObject.GetBindingExpression(TextBox.TextProperty); 
      AssociatedObject.TextChanged += OnTextChanged; 
     } 

     /// <summary> 
     /// Called when the behavior is being detached from its AssociatedObject, but before it has actually occurred. 
     /// </summary> 
     /// <remarks> 
     /// Override this to unhook functionality from the AssociatedObject. 
     /// </remarks> 
     protected override void OnDetaching() 
     { 
      base.OnDetaching(); 

      // Un-hook events 
      AssociatedObject.TextChanged -= OnTextChanged; 
      _expression = null; 
     } 

     /// <summary> 
     /// Updates the source property when the text is changed. 
     /// </summary> 
     private void OnTextChanged(object sender, EventArgs args) 
     { 
      _expression.UpdateSource(); 
     } 
    } 
} 

這是一個基本清理後的版本Microsoft Prism 4.1代碼(如果要瀏覽其餘部分,請參閱Silverlight \ Prism.Interactivity項目)。

現在如何使用它:

  1. 添加到System.Windows.Interactivity集的引用到您的Windows Phone項目。
  2. 在您要使用的行爲,增加一個XAML參考裝配的每一頁: 的xmlns:I = 「CLR的命名空間:System.Windows.Interactivity;裝配= System.Windows.Interactivity」
  3. 每個TextBox的XAML裏面要應用bahvior(它已經具備了雙向綁定到你的源屬性),添加以下內容:

    <我:Interaction.Behaviors>
    <我:UpdateTextBindingOnPropertyChanged />
    < /i:Interaction.Behaviors>

    注意:「my:」前綴在代碼中可能有所不同。這只是添加行爲類的名稱空間引用。

0

此鏈接有一個在WinRT中完美運行的解決方案。他繼承了TextBox並添加了一個新屬性:BindableText。

http://www.familie-smits.com/post/2012/07/29/UpdateSourceTrigger-in-WinRT.aspx

+0

擴展TextBox聽起來不是一個好主意。這實際上是一個非常糟糕的主意。事實上這是最糟糕的想法。 AttachProperty可能會更好。但是,這種解決方案將您限制爲一個控件,這是我完全不同意它的原因之一。如果我們想在另一個控件上使用相同的行爲呢? – 2016-01-25 08:45:40

+0

包含網址已過期 – Rajiv 2016-08-01 11:26:37

4

嘗試UpdateSourceTrigger屬性設置爲 '的PropertyChanged'

這樣

Property="{Binding PropertyBinding, Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}"