В: Почему мой пользовательский TextBox UserControl с использованием MultiBinding и IMultiValueConverter получает свой метод Convert(), вызываемый только один раз (во время instanciation)?MultiBinding и IMultiValueConverter Convert(), вызываемый только один раз
Я определил UserControl, который требует MultiBinding
и IMultiValueConverter
для того, чтобы изменить свое поведение/презентацию на 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>
При выполнении приложения, то все элементы управления UserControl правильно инстанциирован. Однако метод IMultiValueConverter.Convert()
получил название только один раз.
Использование простой Binding
+ IValueConverter
с постоянной ConvertParameter
работал большой: Convert()
метод преобразователя был бы дозвонились Каждый раз, когда TextBox
содержится внутри UserControl
была его свойство Текст изменен.
Дизайн изменился, и мне пришлось прибегнуть к помощи MultiBinding
+ IMultiValueConverter
, и теперь метод Convert()
только вызывается один раз, и TextBox.Text
свойство никогда не обновляется на LostFocus()
события.
Что дает?
MultiValueConverter определяется ниже. Я просто завершаю IMultiValueConverter на IValueConverter для повторного использования существующего кода.
[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) };
}
}
Когда вы запускаете это в отладчике, вы получаете исключения в окне вывода? – Jay
Никакого исключения вообще! Похоже, что привязка работает нормально, но только при instanciation. –