對於我的WPF應用程序,我創建了基於TextBox的幾個自定義控件。這些包括NumericTextBox,WatermarkTextBox和ReturnTextBox。MaxLength屬性在我的自定義文本框中打破
數字和水印從繼承自TextBox的ReturnTextBox繼承。
當我使用我的任何自定義文本框時,它們都很棒。一個問題似乎是NumericTextBox和MaxLength屬性。該屬性現在被忽略,不起作用。在我的任何自定義控件中沒有任何代碼覆蓋或混淆MaxLength屬性。
當我使用的MaxLength我ReturnTextBox,它的工作原理就像你所期望的:
<ui:ReturnTextBox MaxLength="35" Width="500" Background="LightYellow" Text="{Binding BrRptCorpName, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" TabIndex="2" />
然而,當我使用屬性上我的NumericTextBox它被忽略並不起作用:
<ui:NumericTextBox MaxLength="9" Background="LightYellow" Text="{Binding BrRptAmt, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged, ValidatesOnDataErrors=True}" TabIndex="1" />
任何人都可以幫我弄清楚爲什麼MaxLength停止工作?是否因爲NumericTextBox不直接從TextBox繼承?我應該重寫ReturnTextBox中的MaxLength屬性,以便Numeric可以使用它?
的代碼已更新
ReturnTextBox類:
public class ReturnTextBox : TextBox
{
static ReturnTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(ReturnTextBox), new FrameworkPropertyMetadata(typeof(ReturnTextBox)));
}
protected override void OnPreviewKeyDown(KeyEventArgs e)
{
if (e.Key == Key.Return)
{
e.Handled = true;
MoveFocus(new TraversalRequest(FocusNavigationDirection.Next));
}
base.OnPreviewKeyDown(e);
}
}
NumericTextBox
public class NumericTextBox : ReturnTextBox
{
#region Base Class Overrides
static NumericTextBox()
{
DefaultStyleKeyProperty.OverrideMetadata(typeof(NumericTextBox), new FrameworkPropertyMetadata(typeof(NumericTextBox)));
}
public static readonly DependencyProperty TypeProperty = DependencyProperty.Register("Type",
typeof(NumericType), typeof(NumericTextBox), new UIPropertyMetadata (NumericType.Integer));
public static readonly DependencyProperty SelectAllOnGotFocusProperty = DependencyProperty.Register("SelectAllOnGotFocus",
typeof(bool), typeof(NumericTextBox), new PropertyMetadata(false));
[Description("Numeric Type of the TextBox"), Category("Common Properties")]
public NumericType Type
{
get { return (NumericType)GetValue(TypeProperty); }
set { SetValue(TypeProperty, value); }
}
[Description("Select text on focus"), Category("Common Properties")]
public bool SelectAllOnGotFocus
{
get
{
return (bool)GetValue(SelectAllOnGotFocusProperty);
}
set
{
SetValue(SelectAllOnGotFocusProperty, value);
}
}
protected override void OnPreviewTextInput(TextCompositionEventArgs e)
{
Text = ValidateValue(Type, Text);
bool isValid = IsSymbolValid(Type, e.Text);
e.Handled = !isValid;
if (isValid)
{
int caret = CaretIndex;
string text = Text;
bool textInserted = false;
int selectionLength = 0;
if (SelectionLength > 0)
{
text = text.Substring(0, SelectionStart) + text.Substring(SelectionStart + SelectionLength);
caret = SelectionStart;
}
if (e.Text == NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
{
while (true)
{
int ind = text.IndexOf(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator);
if (ind == -1)
break;
text = text.Substring(0, ind) + text.Substring(ind + 1);
if (caret > ind)
caret--;
}
if (caret == 0)
{
text = "0" + text;
caret++;
}
else
{
if (caret == 1 && string.Empty + text[0] == NumberFormatInfo.CurrentInfo.NegativeSign)
{
text = NumberFormatInfo.CurrentInfo.NegativeSign + "0" + text.Substring(1);
caret++;
}
}
if (caret == text.Length)
{
selectionLength = 1;
textInserted = true;
text = text + NumberFormatInfo.CurrentInfo.NumberDecimalSeparator + "0";
caret++;
}
}
else if (e.Text == NumberFormatInfo.CurrentInfo.NegativeSign)
{
textInserted = true;
if (Text.Contains(NumberFormatInfo.CurrentInfo.NegativeSign))
{
text = text.Replace(NumberFormatInfo.CurrentInfo.NegativeSign, string.Empty);
if (caret != 0)
caret--;
}
else
{
text = NumberFormatInfo.CurrentInfo.NegativeSign + Text;
caret++;
}
}
if (!textInserted)
{
text = text.Substring(0, caret) + e.Text +
((caret < Text.Length) ? text.Substring(caret) : string.Empty);
caret++;
}
try
{
double val = Convert.ToDouble(text);
double newVal = val;//ValidateLimits(GetMinimumValue(_this), GetMaximumValue(_this), val);
if (val != newVal)
{
text = newVal.ToString();
}
else if (val == 0)
{
if (!text.Contains(NumberFormatInfo.CurrentInfo.NumberDecimalSeparator))
text = "0";
}
}
catch
{
text = "0";
}
while (text.Length > 1 && text[0] == '0' && string.Empty + text[1] != NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
{
text = text.Substring(1);
if (caret > 0)
caret--;
}
while (text.Length > 2 && string.Empty + text[0] == NumberFormatInfo.CurrentInfo.NegativeSign && text[1] == '0' && string.Empty + text[2] != NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
{
text = NumberFormatInfo.CurrentInfo.NegativeSign + text.Substring(2);
if (caret > 1)
caret--;
}
if (caret > text.Length)
caret = text.Length;
Text = text;
CaretIndex = caret;
SelectionStart = caret;
SelectionLength = selectionLength;
e.Handled = true;
}
base.OnPreviewTextInput(e);
}
private static string ValidateValue(NumericType type, string value)
{
if (string.IsNullOrEmpty(value))
return string.Empty;
value = value.Trim();
switch (type)
{
case NumericType.Integer:
try
{
Convert.ToInt64(value);
return value;
}
catch
{
}
return string.Empty;
case NumericType.Decimal:
try
{
Convert.ToDouble(value);
return value;
}
catch
{
}
return string.Empty;
}
return value;
}
private static bool IsSymbolValid(NumericType type, string str)
{
switch (type)
{
case NumericType.Decimal:
if (str == NumberFormatInfo.CurrentInfo.NegativeSign ||
str == NumberFormatInfo.CurrentInfo.NumberDecimalSeparator)
return true;
break;
case NumericType.Integer:
if (str == NumberFormatInfo.CurrentInfo.NegativeSign)
return true;
break;
case NumericType.Any:
return true;
}
if (type.Equals(NumericType.Integer) || type.Equals(NumericType.Decimal))
{
foreach (char ch in str)
{
if (!Char.IsDigit(ch))
return false;
}
return true;
}
return false;
}
protected override void OnGotFocus(RoutedEventArgs e)
{
base.OnGotFocus(e);
if (SelectAllOnGotFocus)
SelectAll();
}
protected override void OnPreviewMouseLeftButtonDown(MouseButtonEventArgs e)
{
if (!IsKeyboardFocused && SelectAllOnGotFocus)
{
e.Handled = true;
Focus();
}
base.OnPreviewMouseLeftButtonDown(e);
}
正如你可以看到我從來沒有在這兩種控制的覆蓋或對MaxLength屬性的任何變化。然而,MaxLength與ReturnTextBox一起使用,並不適用於NumericTextBox。
謝謝你的幫助!
顯示您的視圖模型屬性,其中BrRptAmt是如何定義你的MaxLength。 XAML是不夠的。 –
您是通過代碼還是鍵盤輸入來填充NumericTextBox?您可以從代碼創建超過MaxLegnth的文本。該約束僅用於運行時擊鍵。 – drankin2112
如果您發佈了您的NumericTextBox代碼,我會提供幫助。否則,我們只是猜測。 –