我怎样才能将double值格式化为相对于其他绑定值?

时间:2017-01-23 15:25:05

标签: wpf mvvm data-binding

我有一个包含集合的View Model。每个收集项目都有仪器和价格属性。 Instrument对象具有Name和decimal number number属性。

当我将集合绑定到我的View的DataGrid控件时,我想格式化相对于项目的乐器小数位数属性的价格列,如下所示;

AAPL 100.89 AAPL的小数位数为2

EURUSD 1.12345 EURUSD的小数位数为5

我该如何编写这种类型的动态转换器?或者有更好的解决方案吗?

1 个答案:

答案 0 :(得分:0)

在回答问题之前,我想详细说明问题。我有一个WatchListItem类,它具有工具,最后价格,买入价,卖价属性。在我的View Model中有WatchListItems属性,它是WatchListItem的列表,我将它绑定到我的View的DataGrid控件。 DataGrid控件每个属性有3列。在运行时,我想根据工具的刻度尺寸显示格式的最后,询价和买价。

稍微搜索一下后,我发现这个问题可以解决绑定和多重绑定。

如果要使用Binding,则必须将列绑定到WatchListItem。然后你可以编写实现IValueConverter的类并通过静态资源在xaml中使用它,并且对于转换器知道哪个价格想要格式化你必须给出转换参数" Last"或者"出价"或者"问问"。我不喜欢这个解决方案,因为打开关于转换参数的拼写错误。

我使用了MultiBinding和IMultiValueConverter,如下所示。

<强>转换器

[ValueConversion(typeof(double), typeof(string))]
public class PriceToStringConverter : IMultiValueConverter
{
    #region Implementation of IMultiValueConverter

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
    {
        if (targetType != typeof(string))
            throw new ArgumentException("The target type must be a string.");

        var instrument = (IInstrument) values[0];
        var instrumentPrice = (double) values[1];
        var instrumentTickSizeParts = instrument.TickSize.ToString("0.#####", culture).Split('.');
        if (instrumentTickSizeParts.Length == 1)
            return instrumentPrice.ToString(culture);

        var format = $"0.{string.Empty.PadRight(instrumentTickSizeParts[1].Length, '0')}";
        return instrumentPrice.ToString(format, culture);
    }

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

    #endregion
}

<强> XAML

    <DataGrid ItemsSource="{Binding CurrentWatchList.WatchListItems}">
        <DataGrid.Resources>
            <converters:PriceToStringConverter x:Key="PriceToStringConverter"/>
        </DataGrid.Resources>
        <DataGrid.Columns>
            <DataGridTextColumn Header="Instrument" Binding="{Binding Instrument.Name}"/>
            <DataGridTextColumn Header="Time" Binding="{Binding Time, StringFormat={}{0:HH:mm:ss}}"/>
            <DataGridTextColumn Header="Last">
                <DataGridTextColumn.Binding>
                    <MultiBinding Converter="{StaticResource PriceToStringConverter}">
                        <Binding Path="Instrument"/>
                        <Binding Path="Last"/>
                    </MultiBinding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>
            <DataGridTextColumn Header="Bid">
                <DataGridTextColumn.Binding>
                    <MultiBinding Converter="{StaticResource PriceToStringConverter}">
                        <Binding Path="Instrument"/>
                        <Binding Path="Bid"/>
                    </MultiBinding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>
            <DataGridTextColumn Header="Ask">
                <DataGridTextColumn.Binding>
                    <MultiBinding Converter="{StaticResource PriceToStringConverter}">
                        <Binding Path="Instrument"/>
                        <Binding Path="Ask"/>
                    </MultiBinding>
                </DataGridTextColumn.Binding>
            </DataGridTextColumn>
        </DataGrid.Columns>
    </DataGrid>