我正在开发一个自定义的货币编辑文本框。
我看到了一些现成的,但它们很复杂和/或不太可用,迫使你采用不良做法(例如硬编码控件上应该使用的名称)。
所以我决定自己做,但我在处理绑定选项时遇到了麻烦,因为分配给绑定属性的属性必须是十进制数,但TextBox控件的Text属性接受字符串。
我想到的答案是,也许可以覆盖基类(TextBox)中Text属性的访问方法(getter和setter),但这是不允许的。
我的绑定应该设置为值,该值将TextBox的Text属性格式化为文本(带有货币符号和其他所有内容),但在Get方法中将其转换回数字数据类型。
这是我目前取得的成果:
我看到了一些现成的,但它们很复杂和/或不太可用,迫使你采用不良做法(例如硬编码控件上应该使用的名称)。
所以我决定自己做,但我在处理绑定选项时遇到了麻烦,因为分配给绑定属性的属性必须是十进制数,但TextBox控件的Text属性接受字符串。
我想到的答案是,也许可以覆盖基类(TextBox)中Text属性的访问方法(getter和setter),但这是不允许的。
我的绑定应该设置为值,该值将TextBox的Text属性格式化为文本(带有货币符号和其他所有内容),但在Get方法中将其转换回数字数据类型。
这是我目前取得的成果:
public class CurrencyTextBox : TextBox
{
private bool IsValidKey(Key key)
{
int k = (int)key;
return ((k >= 34 && k <= 43) //digits 0 to 9
|| (k >= 74 && k <= 83) //numeric keypad 0 to 9
|| (k == 2) //back space
|| (k == 32) //delete
);
}
private void Format()
{
//formatting decimal to currency text here
//Done! no problems here
}
private void FormatBack()
{
//formatting currency text to decimal here
//Done! no problems here
}
private void ValueChanged(object sender, TextChangedEventArgs e)
{
this.Format();
}
private void MouseClicked(object sender, MouseButtonEventArgs e)
{
this.Format();
// Prevent changing the caret index
this.CaretIndex = this.Text.Length;
e.Handled = true;
}
private void MouseReleased(object sender, MouseButtonEventArgs e)
{
this.Format();
// Prevent changing the caret index
this.CaretIndex = this.Text.Length;
e.Handled = true;
}
private void KeyPressed(object sender, KeyEventArgs e)
{
if (IsValidKey(e.Key))
e.Handled = true;
if (Keyboard.Modifiers != ModifierKeys.None)
return;
this.Format();
}
private void PastingEventHandler(object sender, DataObjectEventArgs e)
{
// Prevent copy/paste
e.CancelCommand();
}
public override void OnApplyTemplate()
{
base.OnApplyTemplate();
// Disable copy/paste
DataObject.AddCopyingHandler(this, PastingEventHandler);
DataObject.AddPastingHandler(this, PastingEventHandler);
this.CaretIndex = this.Text.Length;
this.PreviewKeyUp += KeyPressed;
this.PreviewMouseDown += MouseClicked;
this.PreviewMouseUp += MouseReleased;
this.TextChanged += ValueChanged;
this.Format();
}
}
以下是 XAML 代码:
<MyNamespace:CurrencyTextBox x:Name="TxbCurrency" Text="{Binding Path=DataContext.Element.Currency, ValidatesOnDataErrors=True}" />
到目前为止,一切都很好!十进制属性到文本框文本的绑定是“正确的”。但是,如何在编辑后从文本获取十进制数现在是问题所在。
从十进制到.Text的绑定使用装箱来隐藏ToString()方法。
问题在这里:
在这种情况下,我如何重载Parse()方法,以使用我的FormatBack()方法从TextBox的Text中获取十进制数?