2010-08-24 23 views
1

問:爲什麼使用MultiBinding和IMultiValueConverter的自定義TextBox UserControl只獲得一次調用的Convert()方法(在實例化期間)?MultiBinding和IMultiValueConverter Convert()僅調用一次

我已經定義了需要MultiBindingIMultiValueConverter爲了在2 indenpendant DependencyProperty改變其行爲/演示一個用戶控件。

<proj:MyControl Value="10" Digits="1" /> 

用戶控件:

<UserControl x:Class="MyControl" 
      x:Name="uc" 
      ...> 

    <UserControl.Resources> 
     <conv:DecimalToStringMultiConverter x:Key="DecToString" /> 
    </UserControl.Resources> 

    [...] 

    <Grid> 
     <ctrl:VTextBox x:Name="vTb" Grid.Column="0" Margin="0,0,2,0"> 
      <ctrl:VTextBox.Text> 
       <MultiBinding Converter="{StaticResource DecToString}" UpdateSourceTrigger="LostFocus" Mode="TwoWay"> 
        <Binding ElementName="uc" Path="Value" Mode="TwoWay" /> 
        <Binding ElementName="uc" Path="Digits" Mode="TwoWay" /> 
       </MultiBinding> 
      </ctrl:VTextBox.Text> 
     </ctrl:VTextBox> 
    </Grid> 
</UserControl> 

當執行應用程序時,用戶控件都正確地實例化。然而,IMultiValueConverter.Convert()方法被稱爲只有一次

使用一個簡單的Binding + IValueConverter以恆定ConvertParameter偉大的工作:轉換器的Convert()方法將被調用每次包含UserControlTextBox有它的Text屬性更改。

設計改變了,我不得不求助於使用MultiBinding + IMultiValueConverter,現在Convert()方法只被調用一次,TextBox.Text屬性從未於LostFocus()事件更新。

什麼給?

MultiValueConverter的定義如下。我只是在IValueConverter上包裝IMultiValueConverter以重用現有的代碼。

[ValueConversion(/*sourceType*/ typeof(Decimal), /*targetType*/ typeof(string))] 
public class DecimalToStringConverter : IValueConverter 
{ 
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) 
      return "0.00"; 

     int? digits = parameter as int?; 

     if(digits == null) 
      digits = 2; 

     NumberFormatInfo nfi = (NumberFormatInfo) CultureInfo.InvariantCulture.NumberFormat.Clone(); 
     nfi.NumberGroupSeparator = " "; 
     nfi.CurrencyDecimalSeparator = "."; 
     nfi.NumberDecimalDigits = (int)digits; 

     return ((decimal)value).ToString("n", nfi); 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) 
    { 
     if (value == null) 
      return 0.00m; 

     decimal d; 

     return decimal.TryParse((string)value, out d) ? d : 0.00m; 
    } 
} 

[ValueConversion(/*sourceType*/ typeof(Decimal), /*targetType*/ typeof(string))] 
public class DecimalToStringMultiConverter : IMultiValueConverter 
{ 
    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) 
    { 
     DecimalToStringConverter conv = new DecimalToStringConverter(); 
     return conv.Convert(values[0], targetType, values.Length > 1 ? values[1] : null, culture); 
    } 

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) 
    { 
     DecimalToStringConverter conv = new DecimalToStringConverter(); 
     return new[] { conv.ConvertBack(value, targetTypes[0], null, culture) }; 
    } 
} 
+0

當你在調試器中運行它時,你會在輸出窗口中看到異常嗎? – Jay 2010-08-24 19:44:48

+0

沒有任何異常!綁定似乎工作正常,但只在instanciation。 – 2010-08-24 20:18:01

回答

0

看起來好像你對Binding和TextBox的更新行爲有一些矛盾的期望。多次調用轉換的唯一原因是數字或值的值多次更改,並且您的發佈代碼中沒有任何內容表明會發生此情況。對TextBox.Text的更改不會導致調用轉換,而應該在每次更改+ LostFocus時調用ConvertBack。你在運行代碼時看到了嗎?

您還需要從您的ConvertBack方法返回兩個值,而不是現在那裏的值,以便爲MultiBinding中使用的綁定提供值。

+0

你說得對。我的理解是,傳統的Binding對Text屬性進行任何更改都會更新綁定的DependencyProperty(在本例中爲Value)。在更新Value之後,Convert()方法被調用(爲了簡化,我在上面的例子中刪除了我的自定義格式化和其他內容)。 - 但是,MultiBinding雖然更新了Value,但看起來並不像觸發Convert()方法。就像2way綁定被破壞了一樣......我添加了一些代碼隱藏來更新Value(並使用OneWay綁定)而現在一切都很好,謝謝! – 2010-08-26 15:31:06

相關問題