2017-07-10 45 views
0

我有基於TextBox控件一個WPF控制更新次要屬性:管理該數值從一個DependencyProperty

public class DecimalTextBox : TextBox 

我有一個綁定到一個依賴屬性,並負責設置文本屬性:

public decimal NumericValue 
{ 
    get { return (decimal)GetValue(NumericValueProperty); } 
    set 
    { 
     if (NumericValue != value) 
     { 
      SetValue(NumericValueProperty, value); 
      SetValue(TextProperty, NumericValue.ToString());      

      System.Diagnostics.Debug.WriteLine($"NumericValue Set to: {value}, formatted: {Text}"); 
     } 
    } 
} 

protected override void OnTextChanged(TextChangedEventArgs e) 
{    
    base.OnTextChanged(e); 

    if (decimal.TryParse(Text, out decimal num)) 
    { 
     SetValue(NumericValueProperty, num); 
    } 
} 

這適用於輸入到文本框本身的值(它更新基礎值等)。但是,NumericValue的綁定屬性更改時,儘管更新NumericValue DP,Text屬性不會更新。在我所做的測試中,看起來原因是上面的set方法在綁定值更新時不會被調用。有問題的結合看起來是這樣的:

<myControls:DecimalTextBox NumericValue="{Binding Path=MyValue, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/> 

任何人都可以點我在正確的方向,爲什麼這個屬性setter不點火,或是否有更好的方式來處理呢?

回答

1

Custom Dependency PropertiesXAML Loading and Dependency Properties解釋,你不應該調用一個依賴屬性的CLR包裝比GetValue什麼都和SetValue

由於當前屬性設置的XAML處理器行爲的WPF實現完全繞過了包裝,所以不應該添加任何其他邏輯進入您的自定義依賴屬性的包裝的設置定義。如果將這樣的邏輯放入集合定義中,那麼當該屬性設置爲XAML而不是代碼時,邏輯將不會被執行。


爲了收到通知價值的變化,你必須註冊依賴屬性的元數據的PropertyChangedCallback

public static readonly DependencyProperty NumericValueProperty = 
    DependencyProperty.Register(
     "NumericValue", typeof(decimal), typeof(DecimalTextBox), 
     new PropertyMetadata(NumericValuePropertyChanged)); 

public decimal NumericValue 
{ 
    get { return (decimal)GetValue(NumericValueProperty); } 
    set { SetValue(NumericValueProperty, value); } 
} 

private static void NumericValuePropertyChanged(
    DependencyObject obj, DependencyPropertyChangedEventArgs e) 
{ 
    var textBox = (DecimalTextBox)obj; 
    textBox.Text = e.NewValue.ToString(); 
} 
0

的WPF綁定實際上並沒有使用你的getter和setter,而是直接依賴屬性NumericValueProperty交互。爲了更新文本,訂閱PropertyChanged事件NumericValueProperty,而不是試圖做任何事情,在二傳手特殊的。

訂閱你的DependencyProperty定義的變化,類似以下內容:

// Using a DependencyProperty as the backing store for NumericValue. This enables animation, styling, binding, etc... 
public static readonly DependencyProperty NumericValueProperty = 
    DependencyProperty.Register("NumericValue", typeof(decimal), typeof(DecimalTextBox), new FrameworkPropertyMetadata(0.0m, new PropertyChangedCallback(OnNumericValueChanged))); 

private static void OnNumericValueChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) 
{ 
    var self = d as DecimalTextBox; 
    // if the new numeric value is different from the text value, update the text 
} 
相關問題