2013年3月3日日曜日

DataBinding(その3)

DataConverterについて
データをBindする途中でデータを変換する機能 

具体的には、「System.Windows.Data.IValueConverter」実装クラスを
Bindingインスタンスの「Converter」プロパティに指定することで実現する。
「IValueConverter」インターフェースのコードは以下の通り

   1: [System.Windows.Data.IValueConverter]::System.Object Convert(System.Object, System.Type, System.Object, System.Globalization.CultureInfo)
   2: [System.Windows.Data.IValueConverter]::System.Object ConvertBack(System.Object, System.Type, System.Object, System.Globalization.CultureInfo)

サンプル画面
image

実際動かして確認してみる。
PowershellだけでWPF表示(Powershell3.0でも2.0でも稼働)
.NetFrameworkは3.0以上が必要
WPFの約束としてPowershellはSTAモードで動く必要あり
以下コードを
①Powershellコンソールにコピペして実行
②ISEで実行する時はすでにSTAモードなので適時修正して実行
注意:ブラウザによってはコピペで行頭に余分な空白が出来てしまうことあり
C:\temp> □'@ ← ここの行の行頭に空白あると動かない


   1: #------------------------------------------------------ 
   2: if ($host.Version.Major -eq 3) {
   3:     powershell.exe
   4: } else {
   5:     powershell.exe -version 2 -sta
   6: }
   7:  
   8: if ($host.Version.Major -eq 3) {
   9:     add-type -assembly WindowsBase,PresentationCore,PresentationFramework,System.Xml,System.xaml
  10: } else {
  11:     add-type -assembly WindowsBase,PresentationCore,PresentationFramework
  12: }
  13:  
  14: $xaml = @'
  15: <Window
  16:     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  17:     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  18:     xmlns:local="clr-namespace:TwoWayConverter;assembly=TwoWayConverter"
  19:     Title="TwoWayConverter" Height="220" Width="275">
  20:  
  21:     <StackPanel>
  22:         <TextBox Margin="10">
  23:             <TextBox.Text>
  24:                 <Binding ElementName="sldrSlider" Path="Value">
  25:                     <Binding.Converter>
  26:                         <local:DisplayTwoDecPlaces/>
  27:                     </Binding.Converter>
  28:                 </Binding>
  29:             </TextBox.Text>
  30:         </TextBox>
  31:         <Slider Name="sldrSlider" TickPlacement="TopLeft" Margin="10"/>
  32:     </StackPanel>
  33: </Window>
  34: '@
  35:  
  36: $code = @'
  37: using System;
  38: using System.Windows.Data;
  39: namespace TwoWayConverter
  40: {
  41:     //[ValueConversion( typeof( double ), typeof( string ) )]
  42:     public class DisplayTwoDecPlaces : IValueConverter
  43:     {
  44:         public object val;
  45:         public Type   typ;
  46:         public object par;
  47:         public System.Globalization.CultureInfo cul;
  48:     
  49:         public object Convert( object value, Type targetType,
  50:         object parameter, System.Globalization.CultureInfo culture )
  51:         {
  52:             val = value;
  53:             typ = targetType;
  54:             par = parameter;
  55:             cul = culture;
  56:         
  57:             double dValue = (double) value;
  58:             return dValue.ToString( "F2" );
  59:         }
  60:         public object ConvertBack( object value, Type targetType,
  61:         object parameter,System.Globalization.CultureInfo culture )
  62:         {
  63:             double dValue;
  64:             double.TryParse( (string) value, out dValue );
  65:             return dValue;
  66:         }
  67:     }
  68: }
  69: '@
  70:  
  71: del C:\temp\work\TwoWayConverter.dll
  72: Add-Type $code -OutputAssembly "c:\temp\work\TwoWayConverter.dll" `
  73:          -ReferencedAssemblies @("WindowsBase","PresentationCore","PresentationFramework")
  74: add-type -Path C:\temp\work\TwoWayConverter.dll
  75:  
  76: $form = [System.Windows.Markup.XamlReader]::Parse($xaml)
  77:  
  78: $Form.ShowDialog() | out-null

Conver機能の設定状況を確認してみる
「TextBox」エレメントの「Text依存関係プロパティ」に紐付された「Bindingインスタンス」に設定されている。以下のように2行実行すると、



   1: $tb = $form.content.children[0]
   2: $tb.GetBindingExpression([System.Windows.Controls.TextBox]::TextProperty).ParentBinding

Bindingインスタンスを表示すると、「Converter」プロパティに設定されている



   1: ValidationRules             : {}
   2: ValidatesOnExceptions       : False
   3: ValidatesOnDataErrors       : False
   4: ValidatesOnNotifyDataErrors : True
   5: Path                        : System.Windows.PropertyPath
   6: XPath                       :
   7: Mode                        : Default
   8: UpdateSourceTrigger         : Default
   9: NotifyOnSourceUpdated       : False
  10: NotifyOnTargetUpdated       : False
  11: NotifyOnValidationError     : False
  12: Converter                   : TwoWayConverter.DisplayTwoDecPlaces    <--★これ!
  13: ConverterParameter          :
  14: ConverterCulture            :
  15: Source                      :
  16: RelativeSource              :
  17: ElementName                 : sldrSlider
  18: IsAsync                     : False
  19: AsyncState                  :
  20: BindsDirectlyToSource       : False
  21: UpdateSourceExceptionFilter :
  22: FallbackValue               : {DependencyProperty.UnsetValue}
  23: StringFormat                :
  24: TargetNullValue             : {DependencyProperty.UnsetValue}
  25: BindingGroupName            :
  26: Delay                       : 0

「Converter」の呼ばれ方状況を確認してみる


$form.content.Children[0].getBindingExpression([System.Windows.Controls.TextBox]::TextProperty).ParentBinding.Converter


以下のような値で、値が変化するたびに次々に呼ばれてるみたい



























Paramコメント
value4.759825328変換してほしい「double」型の値が渡される
targetTypeSystem.String   変換してほしい型は「String」でお願い..
parameter  
cultureen-US 

0 件のコメント:

コメントを投稿