代码之家  ›  专栏  ›  技术社区  ›  Matthew Perron

multibinding和immultiValueConverter convert()只调用一次

  •  2
  • Matthew Perron  · 技术社区  · 14 年前

    问:为什么使用多重绑定和IMultiValueConverter的自定义文本框用户控件只调用一次convert()方法(在声明期间)??

    我定义了一个需要 MultiBinding 和A IMultiValueConverter 为了改变它的行为/表现 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>
    

    在执行应用程序时,用户控件都已正确安装。然而, IMultiValueConverter.Convert() 方法被调用 只有一次 .

    使用简单 Binding + IValueConverter 用常数 ConvertParameter 工作很好:转换器 Convert() 每次调用 TextBox 包含在 UserControl 已更改其文本属性。

    设计改变了,我不得不使用 多重装订 + 多值转换器 现在 转换() 方法只被调用一次,并且 TextBox.Text 属性不会在 LostFocus() 事件。

    给出了什么?

    多值转换器定义如下。我只是将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) };
        }
    }
    
    1 回复  |  直到 14 年前
        1
  •  0
  •   John Bowen    14 年前

    似乎您对绑定和文本框的更新行为有一些相互冲突的期望。转换将被多次调用的唯一原因是,如果数字或值的值多次更改,并且您的已发布代码中没有任何内容指示将发生这种情况。对文本框的更改。文本不会导致调用转换,但应改为调用 折返 每次改变+失去焦点。在运行代码时是否看到了这一点?

    您还需要从convertback方法返回两个值,而不是现在返回的值,以便为多绑定中使用的两个绑定提供值。