データバインディングを行う際に時々必要となる Binding.Converter について以下で説明します。
Binding.Converter は、データバインディングする2つの型が異なる場合に自動的に変換を行うようにする仕組みです。
具体例を示しながら以下記載します。例として byte[] 型のプロパティとデータバインディングして画面に HEX(16進数) 表記でデータ列を表示する、ことを行います。
先に完成イメージを下図に示します。
プログラム内部に10バイトの byte 配列を持ち、値は乱数とします。プログラム起動時 または [Update data] ボタンを押したときにこのデータ配列を更新します。そして画面上にこのデータ列を16進数表記で表示します。
[プログラムソース(MainWindow.xaml)]
<Window xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="RandomBytes.MainWindow" Title="MainWindow" Height="202" Width="417"> <Grid> <Button Content="Quit" Margin="297,116,0,0" VerticalAlignment="Top" HorizontalAlignment="Left" Width="75" Height="26.24" Click="Button_Click"/> <Button Content="Update data" HorizontalAlignment="Left" Margin="297,35,0,0" VerticalAlignment="Top" Width="75" Height="26.24" d:LayoutOverrides="VerticalAlignment" Click="Click_UpdateData" Loaded="MainWindow_Loaded"/> <TextBlock x:Name="data_view" Margin="43,35,135.567,0" TextWrapping="Wrap" Text="TextBlock" VerticalAlignment="Top" d:LayoutOverrides="VerticalAlignment" Height="26.24" FontSize="13.333"/> </Grid> </Window>
ざっくり、以下の手順で作成します。
プログラムソースは以下の通り。
[プログラムソース(MainWindow.xaml.cs)]
using System; using System.ComponentModel; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Data; namespace RandomBytes { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private TestData testData = new TestData(); public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { // TODO: ここにイベント ハンドラーのコードを追加します。 Close(); } void UpdateData() { // 乱数で10バイトを作成 testData.UpdateData(); } private void Click_UpdateData(object sender, RoutedEventArgs e) { UpdateData(); } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { var binding = new Binding(); binding.Source = testData; binding.Path = new PropertyPath("data"); binding.Mode = BindingMode.OneWay; data_view.SetBinding(TextBlock.TextProperty, binding); UpdateData(); } } public class TestData : INotifyPropertyChanged { private const int DataBytes = 10; private byte[] _data = new byte[DataBytes]; private Random random = new Random(); public byte[] data { get { return _data; } } public TestData() { } public void UpdateData() { random.NextBytes(data); NotifyPropertyChanged("data"); } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; void NotifyPropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } #endregion // INotifyPropertyChanged } }
この状態でプログラムを実行すると
となりました。どうやら暗黙の型変換により属性情報に関する文字列が表示されたようです。もちろんプログラミングの意図と異なります。
Binding.Converter の表記を追加して byte[] から string への変換内容を具体的に指示します。
変換内容はインタフェース IValueConverter
を持つクラスで指定します。
using System; using System.ComponentModel; using System.Globalization; using System.Windows; using System.Windows.Controls; using System.Windows.Data; namespace RandomBytes { /// <summary> /// MainWindow.xaml の相互作用ロジック /// </summary> public partial class MainWindow : Window { private TestData testData = new TestData(); public MainWindow() { InitializeComponent(); } private void Button_Click(object sender, System.Windows.RoutedEventArgs e) { // TODO: ここにイベント ハンドラーのコードを追加します。 Close(); } void UpdateData() { // 乱数で10バイトを作成 testData.UpdateData(); } private void Click_UpdateData(object sender, RoutedEventArgs e) { UpdateData(); } private void MainWindow_Loaded(object sender, RoutedEventArgs e) { var binding = new Binding(); binding.Source = testData; binding.Path = new PropertyPath("data"); binding.Converter = new TestConverter(); binding.Mode = BindingMode.OneWay; data_view.SetBinding(TextBlock.TextProperty, binding); UpdateData(); } } public class TestData : INotifyPropertyChanged { private const int DataBytes = 10; private byte[] _data = new byte[DataBytes]; private Random random = new Random(); public byte[] data { get { return _data; } } public TestData() { } public void UpdateData() { random.NextBytes(data); NotifyPropertyChanged("data"); } #region INotifyPropertyChanged public event PropertyChangedEventHandler PropertyChanged; void NotifyPropertyChanged(string info) { if (PropertyChanged != null) { PropertyChanged(this, new PropertyChangedEventArgs(info)); } } #endregion // INotifyPropertyChanged } [ValueConversion(typeof(string), typeof(byte[]))] public class TestConverter : IValueConverter { public object Convert(object value, Type targetType, object parameter, CultureInfo culture) { var data = (byte[])value; string temp = ""; foreach (byte oneByte in data) { temp += oneByte.ToString("X2"); } return temp; } public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) { return null; } } }
これで正常に動作するようになります。
上記プログラムを下記からダウンロード可能です。
本ページの情報は、特記無い限り下記 MIT ライセンスで提供されます。
2024-05-23 | - | ページデザイン更新 |
2013-05-28 | - | 新規作成 |