当前位置:   article > 正文

WPF数据转换_wpf 数字字符串绑定转换

wpf 数字字符串绑定转换

在基本绑定中,信息从源到目标的传递过程中没有任何变化。这看起来是符合逻辑的,但我们并不总是希望出现这种行为。通常,数据源使用的是低级表达方式,我们可能不希望直接在用户界面使用这种低级表达方式。WPF提供了两个工具,来进行数据转换:

字符串格式化

通过设置 Binding.StringFormat 属性对文本形式的数据进行转换——例如包含日期和数字的字符串。

值转换器

该功能更强大,使用该功能可以将任意类型的源数据转换为任意类型的对象表示,然后可以传递到关联的控件。

使用StringFormat属性

  1. <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=Price, StringFormat=ConvertDirectly:{0:C}}"></TextBlock>
  2. <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price, StringFormat={}{0:C}}"></TextBox>
  3. <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=OrderDate, StringFormat={}{0:s}}"></TextBox>

可以看到后面两个StringFormat属性以花括号 {} 开头,完整值是 {}{0:C},而不是 {0:C},第一个则只有 {0:C},这是因为在StringFormat 值以花括号开头时需要 {} 转义序列。

使用值转换器

为创建子转换器需要执行以下四个步骤:

1、创建一个实现IValueConverter接口的类

2、为该类声明添加ValueConversion特性,并指定目标数据类型

3、实现Convert()方法,该方法将数据从原来的格式转换为显示的格式

4、实现ConvertBack()方法,该方法执行反向变换,将值从显示格式转换为原格式

  1. [ValueConversion(typeof(decimal), typeof(string))]
  2. public class PriceConverter : IValueConverter
  3. {
  4. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  5. {
  6. decimal price = (decimal)value;
  7. return price.ToString("C", culture);
  8. }
  9. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  10. {
  11. string price = (string)value;
  12. if (decimal.TryParse(price, System.Globalization.NumberStyles.Any, culture, out decimal result))
  13. {
  14. return result;
  15. }
  16. return value;
  17. }
  18. }

要使用这个转换器,可以将其添加到页面的资源下,然后使用 Binding.Converter 指定。

  1. <Window>
  2. <Window.Resources>
  3. <local:PriceConverter x:Key="priceConverter"/>
  4. <local:PriceToBackgroundConverter x:Key="priceToBackgroundConverter" MinimumPriceToHighlight="100" DefaultBrush="{x:Null}" HighlightBrush="Orange"/>
  5. <local:ImagePathConverter x:Key="imagePathConverter"/>
  6. <local:MultiValueConverter x:Key="multiValueConverter"/>
  7. </Window.Resources>
  8. <TextBox Text="{Binding Path=Price, Converter={StaticResource priceConverter}}"></TextBox>
  9. </Window>

多重绑定

可以将多个字段绑定到同一个输出控件,可以通过 StringFormat 或 MultiBinding.Converter 来格式化数据。多重绑定的值转换器需要实现的接口是 IMultiValueConverter,与 IValueConverter 接口比较类似,只是转换函数的第一个参数改成了数组形式。

  1. <TextBlock Grid.Row="4" Grid.Column="0">
  2. <TextBlock.Text>
  3. <MultiBinding StringFormat="{}{0}, {1}, {2}">
  4. <Binding Path="Price"/>
  5. <Binding Path="OrderDate"/>
  6. <Binding Path="Volume"/>
  7. </MultiBinding>
  8. </TextBlock.Text>
  9. </TextBlock>
  10. <TextBlock Grid.Row="5" Grid.Column="0">
  11. <TextBlock.Text>
  12. <MultiBinding Converter="{StaticResource multiValueConverter}">
  13. <Binding Path="Price"/>
  14. <Binding Path="Volume"/>
  15. </MultiBinding>
  16. </TextBlock.Text>
  17. </TextBlock>
  1. public class MultiValueConverter : IMultiValueConverter
  2. {
  3. public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  4. {
  5. decimal price = (decimal)values[0];
  6. int volume = (int)values[1];
  7. return (price * volume).ToString("C");
  8. }
  9. public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
  10. {
  11. throw new NotSupportedException();
  12. }
  13. }

完整代码如下:

MainWindow.xaml

  1. <Window x:Class="TestDataConverter.MainWindow"
  2. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  3. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  4. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  5. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  6. xmlns:local="clr-namespace:TestDataConverter"
  7. mc:Ignorable="d"
  8. Title="MainWindow" Height="450" Width="800">
  9. <Window.Resources>
  10. <local:PriceConverter x:Key="priceConverter"/>
  11. <local:PriceToBackgroundConverter x:Key="priceToBackgroundConverter" MinimumPriceToHighlight="100" DefaultBrush="{x:Null}" HighlightBrush="Orange"/>
  12. <local:ImagePathConverter x:Key="imagePathConverter"/>
  13. <local:MultiValueConverter x:Key="multiValueConverter"/>
  14. </Window.Resources>
  15. <Grid Name="myGrid" Background="{Binding Path=Price, Converter={StaticResource priceToBackgroundConverter}}">
  16. <Grid.ColumnDefinitions>
  17. <ColumnDefinition/>
  18. <ColumnDefinition/>
  19. </Grid.ColumnDefinitions>
  20. <Grid.RowDefinitions>
  21. <RowDefinition/>
  22. <RowDefinition/>
  23. <RowDefinition/>
  24. <RowDefinition/>
  25. <RowDefinition/>
  26. <RowDefinition/>
  27. </Grid.RowDefinitions>
  28. <TextBlock Grid.Row="0" Grid.Column="0" Text="{Binding Path=Price, StringFormat=ConvertDirectly:{0:C}}"></TextBlock>
  29. <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Path=Price, StringFormat={}{0:C}}"></TextBox>
  30. <TextBlock Grid.Row="1" Grid.Column="0">ConvertWithConverter:</TextBlock>
  31. <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Path=Price, Converter={StaticResource priceConverter}}"></TextBox>
  32. <TextBlock Grid.Row="2" Grid.Column="0">ConvertDateTime:</TextBlock>
  33. <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Path=OrderDate, StringFormat={}{0:s}}"></TextBox>
  34. <TextBlock Grid.Row="3" Grid.Column="0">ConvertImagePath:</TextBlock>
  35. <Image Grid.Row="3" Grid.Column="1" Stretch="None" HorizontalAlignment="Left" Source="{Binding Path=Image, Converter={StaticResource imagePathConverter}}"></Image>
  36. <TextBlock Grid.Row="4" Grid.Column="0">
  37. <TextBlock.Text>
  38. <MultiBinding StringFormat="{}{0}, {1}, {2}">
  39. <Binding Path="Price"/>
  40. <Binding Path="OrderDate"/>
  41. <Binding Path="Volume"/>
  42. </MultiBinding>
  43. </TextBlock.Text>
  44. </TextBlock>
  45. <TextBlock Grid.Row="5" Grid.Column="0">
  46. <TextBlock.Text>
  47. <MultiBinding Converter="{StaticResource multiValueConverter}">
  48. <Binding Path="Price"/>
  49. <Binding Path="Volume"/>
  50. </MultiBinding>
  51. </TextBlock.Text>
  52. </TextBlock>
  53. </Grid>
  54. </Window>

MainWindow.xaml.cs

  1. using System;
  2. using System.Collections.Generic;
  3. using System.ComponentModel;
  4. using System.Globalization;
  5. using System.IO;
  6. using System.Runtime.CompilerServices;
  7. using System.Windows;
  8. using System.Windows.Controls;
  9. using System.Windows.Data;
  10. using System.Windows.Media;
  11. using System.Windows.Media.Imaging;
  12. namespace TestDataConverter;
  13. public class ViewModelBase : INotifyPropertyChanged
  14. {
  15. public event PropertyChangedEventHandler? PropertyChanged;
  16. protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
  17. {
  18. PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
  19. }
  20. protected virtual bool SetProperty<T>(ref T member, T value, [CallerMemberName] string? propertyName = null)
  21. {
  22. if (EqualityComparer<T>.Default.Equals(member, value))
  23. {
  24. return false;
  25. }
  26. member = value;
  27. OnPropertyChanged(propertyName);
  28. return true;
  29. }
  30. }
  31. public class Order : ViewModelBase
  32. {
  33. public decimal price = 0;
  34. public decimal Price { get => price; set => SetProperty(ref price, value); }
  35. public int volume = 0;
  36. public int Volume { get => volume; set => SetProperty(ref volume, value); }
  37. public DateTime orderDate = DateTime.Now;
  38. public DateTime OrderDate { get => orderDate; set => SetProperty(ref orderDate, value); }
  39. public string image = string.Empty;
  40. public string Image { get => image; set => SetProperty(ref image, value); }
  41. }
  42. [ValueConversion(typeof(decimal), typeof(string))]
  43. public class PriceConverter : IValueConverter
  44. {
  45. public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
  46. {
  47. decimal price = (decimal)value;
  48. return price.ToString("C", culture);
  49. }
  50. public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
  51. {
  52. string price = (string)value;
  53. if (decimal.TryParse(price, System.Globalization.NumberStyles.Any, culture, out decimal result))
  54. {
  55. return result;
  56. }
  57. return value;
  58. }
  59. }
  60. [ValueConversion(typeof(decimal), typeof(Brush))]
  61. public class PriceToBackgroundConverter : IValueConverter
  62. {
  63. public decimal MinimumPriceToHighlight { get; set; }
  64. public Brush HighlightBrush { get; set; }
  65. public Brush DefaultBrush { get; set; }
  66. public object Convert(object value, Type targetType, object parameter,
  67. System.Globalization.CultureInfo culture)
  68. {
  69. decimal price = (decimal)value;
  70. if (price >= MinimumPriceToHighlight)
  71. return HighlightBrush;
  72. else
  73. return DefaultBrush;
  74. }
  75. public object ConvertBack(object value, Type targetType, object parameter,
  76. System.Globalization.CultureInfo culture)
  77. {
  78. throw new NotSupportedException();
  79. }
  80. }
  81. public class ImagePathConverter : IValueConverter
  82. {
  83. private string imageDirectory = Directory.GetCurrentDirectory();
  84. public string ImageDirectory
  85. {
  86. get { return imageDirectory; }
  87. set { imageDirectory = value; }
  88. }
  89. public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  90. {
  91. string imagePath = Path.Combine(ImageDirectory, (string)value);
  92. return new BitmapImage(new Uri(imagePath));
  93. }
  94. public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  95. {
  96. throw new NotSupportedException("The method or operation is not implemented.");
  97. }
  98. }
  99. public class MultiValueConverter : IMultiValueConverter
  100. {
  101. public object Convert(object[] values, Type targetType, object parameter, System.Globalization.CultureInfo culture)
  102. {
  103. decimal price = (decimal)values[0];
  104. int volume = (int)values[1];
  105. return (price * volume).ToString("C");
  106. }
  107. public object[] ConvertBack(object value, Type[] targetTypes, object parameter, System.Globalization.CultureInfo culture)
  108. {
  109. throw new NotSupportedException();
  110. }
  111. }
  112. public partial class MainWindow : Window
  113. {
  114. public MainWindow()
  115. {
  116. InitializeComponent();
  117. myGrid.DataContext = Order;
  118. Order.Price = 100;
  119. Order.Volume = 10;
  120. Order.OrderDate = DateTime.Now;
  121. Order.Image = "image1.gif";
  122. }
  123. public Order Order = new Order();
  124. private void Button_Click(object sender, RoutedEventArgs e)
  125. {
  126. Console.WriteLine("");
  127. }
  128. }

声明:本文内容由网友自发贡献,不代表【wpsshop博客】立场,版权归原作者所有,本站不承担相应法律责任。如您发现有侵权的内容,请联系我们。转载请注明出处:https://www.wpsshop.cn/w/你好赵伟/article/detail/928508
推荐阅读
相关标签
  

闽ICP备14008679号