Q: Pourquoi mon UserControl TextBox personnalisé utilisant MultiBinding et IMultiValueConverter obtient-il sa méthode Convert() appelée une seule fois (lors de l'instanciation)?MultiBinding et IMultiValueConverter Convert() appelé une seule fois
J'ai défini un UserControl qui nécessite une MultiBinding
et un IMultiValueConverter
afin de changer son comportement/présentation sur 2 indenpendant DependencyProperty
.
<proj:MyControl Value="10" Digits="1" />
UserControl:
<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>
Lors de l'exécution de l'application, les UserControls sont tous correctement instanciés. Cependant, la méthode IMultiValueConverter.Convert()
est appelée seulement une fois.
l'aide d'un simple, Binding
+ IValueConverter
avec une ConvertParameter
constante a très bien fonctionné: Convert()
méthode du convertisseur obtiendrait appelé chaque fois que le TextBox
contenu à l'intérieur du UserControl
avait sa propriété Text changé.
design changé et je devais recourir à l'aide d'un MultiBinding
+ IMultiValueConverter
, et maintenant la méthode Convert()
n'est appelée une fois, et la propriété TextBox.Text
est jamais mis à jour sur l'événement LostFocus()
.
Ce qui donne?
Le MultiValueConverter est défini comme ci-dessous. Je viens d'enrouler IMultiValueConverter sur IValueConverter pour réutiliser le code existant.
[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) };
}
}
Lorsque vous exécutez ceci dans le débogueur, obtenez-vous des exceptions dans la fenêtre de sortie? – Jay
Aucune exception du tout! La liaison semble bien fonctionner, mais seulement lors de l'instanciation. –