我正在开发一个用于货币编辑的自定义文本框 .
我很复杂和/或不能真正使用,迫使你做坏事(比如硬编码应该在控件上使用的名字) .
所以我've decided to do it myself, but I' m无法使用绑定选项,因为分配给绑定属性的属性必须是小数,但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}" />
到现在为止还挺好!从十进制属性绑定到TextBox文本's is 1505998 . But how to get the decimal back from the text after it' s编辑现在是问题 .
从十进制到.Text的绑定使用装箱来隐藏ToString()方法 .
Question here: 如何在这种情况下从小数重载Parse()方法以使用我的FormatBack()方法从TextBox的Text中获取小数?
4 回答
像这样创建新的
Dependency Property
然后绑定到这个新属性
好吧,为了将来的目的,如果有人遇到同样的麻烦,这里是货币文本框的完整代码 . 随意使用它,修改它,卖它(不要认为它有 Value ,你),或者随意玩它!
和xaml:
看看这篇文章,我认为它会对你有所帮助 . http://www.codeproject.com/Articles/15239/Validation-in-Windows-Presentation-Foundation
或者你可以把这个
并在
PreviewTextInput
事件中提出此事我不认为这实际上是可能的,除了一个只允许数字的盒子的简单情况 . 理想情况下,您需要一个只能包含有效条目的框,但小数包含一些自身无效的字符(如“ - ”和“ . ”) . 用户无法在不将盒子置于无效状态的情况下键入“ - ”开始 .
同样,他们可以输入“1”,然后删除1并使框保持不确定状态 . 当然,它会导致验证错误和红色边框,但您的视图模型仍然认为值为1,并且不知道问题 .
对于正整数,您只能允许数字并在空白时自动插入零(尽管这有点不友好)
对于小数和负整数,我认为你能做的最好的事情就是约束用户可以键入的键,但你仍然需要将你的数字属性包装在一个字符串中并验证它 - 无论是按下OK按钮,还是理想的实现INotifyDataError显示错误并禁用“确定”按钮 .