2014-02-13 22 views
0

爲什麼當我在文本框中輸入文本時,調用後的Coerce函數調用了 MainWindow.Float.Set?Coerce被調用的時間比預期的晚

在輸入文字時,我本來期望:

OnValueCoerce - > OnValueChanged - > MainWindow.Float.Set

,但我得到:

MainWindow.Float.Set - > OnValueCoerce - > OnValueChanged

<Window x:Class="WpfApplication10.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:l="clr-namespace:WpfApplication10" 
     Title="MainWindow" Height="350" Width="525"> 
    <l:TextBoxEx Value="{Binding Float, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}" /> 
</Window> 

...

namespace WpfApplication10 
{ 
    public class TextBoxEx : TextBox 
    { 
     public double Value 
     { 
      get { return (double)GetValue(ValueProperty); } 
      set { SetValue(ValueProperty, value); } 
     } 

     public static readonly DependencyProperty ValueProperty = DependencyProperty.Register("Value", typeof(double), typeof(TextBoxEx), 
      new UIPropertyMetadata(double.NaN, OnValueChanged, OnValueCoerce)); 

     static object OnValueCoerce(DependencyObject _dep, object _value) 
     { 
      return _value; 
     } 

     static void OnValueChanged(DependencyObject _obj, DependencyPropertyChangedEventArgs _arg) 
     { 
      int gotHere = 6; 
     } 

     public TextBoxEx() 
     { 
      var binding = new Binding("Value") 
      { 
       Source = this, 
       UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged, 
       Mode = BindingMode.TwoWay 
      }; 

      SetBinding(TextBox.TextProperty, binding); 
     } 
    } 

    public partial class MainWindow : Window 
    { 
     float m_float = 7.812345678f; 
     public float Float 
     { 
      get { return m_float; } 
      set { m_float = value; } 
     } 

     public MainWindow() 
     { 
      DataContext = this; 
      InitializeComponent(); 
     } 
    } 
} 

回答

0

編輯

這是綁定的方式。假設你有2個屬性A和B.如果A綁定到B,那麼A的值將首先被更新。那麼,你是完全正確地說,「值被寫入不通過的要挾函數去浮‘值’

在您的例子,其中結合數值:。

SetBinding(TextBox.TextProperty, binding); 

值是屬性的在我們的示例是次TextBox.Text。因此,A(Value)將在雙向綁定模式下的值B之前更新。

xaml,「Value」現在屬性B,Float屬性A,因爲Float是結合價值

<l:TextBoxEx Value="{Binding Float, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

因此Float會在更新值之前更新。嘗試在xaml或後面的代碼中繞開Value和Float之間的綁定。

嘗試這是什麼,我想說的一個例證:

  • 某處在構造函數:

    this.SetBinding(myControl.TesterappProperty, new Binding("TesterApp2") { Source=this,Mode=BindingMode.TwoWay}); 
    Testerapp = "hello"; 
    
    this.SetBinding(myControl.TesterApp2Property, new Binding("Testerapp") { Source=this,Mode=BindingMode.TwoWay}); 
    Testerapp = "hello2"; 
    
  • 和2個屬性如下所示:

    public string Testerapp 
    { 
        get { return (string)GetValue(TesterappProperty); } 
        set { SetValue(TesterappProperty, value); } 
    } 
    
    //Register Dependency Testerapp Property 
    public static readonly DependencyProperty TesterappProperty = 
        DependencyProperty.Register("Testerapp", typeof(string), typeof(myControl), new PropertyMetadata("myDefault", OnTesterappPropertyChanged,mycoerce)); 
    
    private static object mycoerce(DependencyObject d, object baseValue) 
    { 
        G2ListBox obj = d as myControl; 
        if(obj!= null) 
        { 
         string s = obj.Testerapp; 
        } 
        return baseValue; 
    } 
    
    //Register Dependency TesterApp2 Property 
    public static readonly DependencyProperty TesterApp2Property = 
        DependencyProperty.Register("TesterApp2", typeof(string), typeof(myControl), new PropertyMetadata("myDefault2", OnTesterApp2PropertyChanged, mycoerce2)); 
    
    private static object mycoerce2(DependencyObject d, object baseValue) 
    { 
        G2ListBox obj = d as myControl; 
        if (obj != null) 
        { 
         string s = obj.Testerapp; 
        } 
        return baseValue; 
    } 
    

設置br在每個脅迫方法中使用eak點並查看每次哪個被首先擊中。這可能解釋我想說的更好一點。

再次 - 我不知道它爲什麼會這樣做,但我遇到過類似的問題,並通過創建另一個屬性(在yourcase - External Value屬性中)解決它。您擁有的value屬性綁定到Textbox並變爲私有;和外部財產是有限的,因爲你現在在XAML。我想你可能也只是訂閱Textbox.PropertyChanged事件而不是創建2個屬性。然後通過事件處理來強制執行。

然而,這只是一些解決方案,我知道它並沒有完全解釋你的問題,爲什麼會發生。我想要做綁定你需要一個重要的層次結構(哪個屬性值應該先被更新),這就是MS如何決定去做的。
我的第一個想法也是期望一個邏輯流(即如果文本框的值改變,然後改變值然後浮動改變,並且類似地,如果浮動=>值=>文本框),但它似乎並不像這是真正的綁定背後的機制。
但現在做的方式可能實際上會更好,因爲現在您可以選擇哪個屬性值需要先更新。

+0

問題是,當你輸入文本時,該值被寫入到Float而沒有經過「Value」的強制函數,當Text被綁定到Value時它沒有任何意義,所以它應該先通過Value。它的行爲就像文本直接綁定到Float – pastillman

+0

爲了更加清晰,我編輯了答案。 – DaClan

相關問題