Quantcast
Channel: C#タグが付けられた新着記事 - Qiita
Viewing all articles
Browse latest Browse all 9309

WPFでTextBoxにdoubleをBindingする

$
0
0

WPFでTextBoxにdoubleをBindingすると

  • 文字の末尾に小数点を入力できない
  • 1.002の2を消すと1.00ではなく1になる

などの動作になります。

これはBindingしている値をTextBoxにも即反映させるという動作になっているからです。

1.002の末尾の2を消した際の動作は下記のようになります。

  1. Text1.00に更新
  2. Binding Sourceのdoubleが(double)1に更新
  3. Text1に更新

雑な解決

起動時に

App.xaml.cs
System.Windows.FrameworkCompatibilityPreferences.KeepTextBoxDisplaySynchronizedWithTextProperty=false;

と設定すれば解決です。
Bindingしている値をTextBoxにも即反映させないようにします。

.NET Framework 4.5以前はこれがデフォルトです。

解決

Textプロパティを更新する前に別のプロパティでチェックを行うことで期待する動作を実現します。

Textは設定せずにDoubleTextのみを使います。

<myControl:DoubleTextBoxDoubleText="{Binding Double1, UpdateSourceTrigger=PropertyChanged}"/>
usingSystem;usingSystem.Windows;usingSystem.Windows.Controls;usingSystem.Windows.Data;publicclassDoubleTextBox:TextBox{publicstringDoubleText{get=>(string)GetValue(DoubleTextProperty);set=>SetValue(DoubleTextProperty,value);}publicstaticreadonlyDependencyPropertyDoubleTextProperty=DependencyProperty.Register(nameof(DoubleText),typeof(string),typeof(DoubleTextBox),newFrameworkPropertyMetadata(string.Empty,FrameworkPropertyMetadataOptions.BindsTwoWayByDefault|FrameworkPropertyMetadataOptions.Journal,newPropertyChangedCallback(OnDoubleTextChanged),null,true,UpdateSourceTrigger.LostFocus));privatestaticvoidOnDoubleTextChanged(DependencyObjectd,DependencyPropertyChangedEventArgse){if(disTextBoxtextBox){varcurrentText=textBox.Text;varnewText=(string)e.NewValue;if(currentText==newText)return;if(double.TryParse(currentText,outvarcurrentDouble)&&double.TryParse(newText,outvarnewDouble)&&currentDouble==newDouble)return;textBox.Text=newText;}}protectedoverridevoidOnTextChanged(TextChangedEventArgse){base.OnTextChanged(e);this.DoubleText=this.Text;}}

動作の解説

これによって、1.002の末尾の2を消した際の動作は下記のようになります。

  1. Text1.00に更新
  2. DoubleText1.00に更新
  3. Binding Sourceのdoubleが(double)1に更新
  4. DoubleText1に更新
  5. 11.00はともにdouble値として等しいのでTextは更新されない

Textが更新された場合の動作

キーの入力などでTextが更新されたときはその値がそのままDoubleTextに反映されます。
Binding Sourceへも同様に反映されます。

DoubleText(あるいはBinding Source)が更新された場合の動作

基本的にはTextに反映されます。
ただし、DoubleTextTextをそれぞれdoubleに変換して同じ値になる場合はTextを更新しません。


Viewing all articles
Browse latest Browse all 9309

Trending Articles