为什么在这个多重绑定中忽略了我的字符串格式化程序?

时间:2014-02-05 15:37:56

标签: c# wpf

我想创建一个多重绑定并使用转换器来转换数字。

<MultiBinding StringFormat="{}{0:F2} {1} {2:F2}">
   <Binding Path="MyDouble"></Binding>
   <Binding Path="MyDouble"></Binding>
   <Binding Path="MyDouble" Converter="{StaticResource myConv}"></Binding>
</MultiBinding>

前两个绑定格式正确。但第三,我使用自定义IValueConverter转换显示值,它只是忽略格式字符串!

有人知道为什么吗?我怎么能绕过它呢?

请注意,我不希望转换器进行字符串格式化,它应该只进行一些单位转换(例如米/英尺)。我计划将转换器重新用于各种其他控件,因此格式化内容应由控件(xaml格式字符串)定义。

完整的代码:

<Window x:Class="MultiBinding.Window1"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:src="clr-namespace:MultiBinding"
    Title="Window1" Height="300" Width="300">
    <Window.Resources>
        <src:MyConverter x:Key="myConv"></src:MyConverter>
    </Window.Resources>

    <Grid>
        <TextBlock>
            <TextBlock.Text>
                <MultiBinding StringFormat="{}{0:F2} {1} {2:F2}">
                    <Binding Path="MyDouble"></Binding>
                    <Binding Path="MyDouble"></Binding>
                    <Binding Path="MyDouble" Converter="{StaticResource myConv}"></Binding>
                </MultiBinding>
            </TextBlock.Text>
        </TextBlock>
    </Grid>
</Window>

这是我的代码背后:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace MultiBinding
{
    /// <summary>
    /// Interaction logic for Window1.xaml
    /// </summary>
    public partial class Window1 : Window
    {
        public Window1()
        {
            InitializeComponent();
            DataContext = new ViewModel(); 
        }
    }

    public class ViewModel{

        double myDouble = 1.4546012347;
        string myString = "hEllo";

        public double MyDouble { get { return myDouble; } }
        public string MyString { get { return myString; } }
    }

    public class MyConverter : IValueConverter
    {
        public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            return 9.3423423f; 
        }

        public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
        {
            throw new NotImplementedException();
        }
    }
}

2 个答案:

答案 0 :(得分:3)

我可以在WPF 3.0上重现您的行为,但不能在4.0或4.5上重现您的行为。似乎转换后的值在3.0中没有正确格式化。

一种解决方法是使用MultiBinding本身上的单独转换器进行格式化,这样可以继续重用现有的值转换器:

<Grid>
  <TextBlock>
    <TextBlock.Text>
      <MultiBinding Converter="{src:StringFormatConverter '{}{0:F2} {1} {2:F2}'}">
        <Binding Path="MyDouble" />
        <Binding Path="MyDouble" />
        <Binding Path="MyDouble" Converter="{StaticResource myConv}" />
      </MultiBinding>
    </TextBlock.Text>
  </TextBlock>
</Grid>

转换器实现示例:

public class StringFormatConverter : MarkupExtension, IMultiValueConverter
{
    [ConstructorArgument("formatString")]
    public string FormatString { get; set; }

    public StringFormatConverter() {}

    public StringFormatConverter(string formatString)
    {
        this.FormatString = formatString;
    }

    public object Convert(
        object[] values,
        Type targetType,
        object parameter,
        CultureInfo culture)
    {
        return string.Format(culture, this.FormatString, values);
    }

    public object[] ConvertBack(
        object value,
        Type[] targetTypes,
        object parameter,
        CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return this;
    }
}

答案 1 :(得分:0)

尝试以下方法:

<MultiBinding StringFormat="{}{0:F2} {1} {2:#.##}">
    ...