我在动态WPF应用程序上使用VS 2015,其中控件及其绑定在代码隐藏中生成。 现在我想实现一个TextBox,它绑定到double类型的数据表列。 此外,在我的TextBox的构建器类中,我尝试设置Format和MaxLength。 一切正常。 格式和MaxLength都可以,但是当我想输入或编辑某些内容时,这很难做到。 客户永远不会接受。 我该怎么办?
这里我称之为构建器类:
CreateTextbox(viewmodel, "table1", "Menge", 20, 40, 60, "#0.0000", 2, 4);
这是创建并返回TextBox的公共方法。
/// <summary>
/// Create and returns a textbox.
/// </summary>
/// <param name="viewmodel">The viewmodel.</param>
/// <param name="tablename">The name of the datatable.</param>
/// <param name="sourceColumn">The column to which we want to bind the textbox.</param>
/// <param name="leftPos">The left position.</param>
/// <param name="topPos">The top position.</param>
/// <param name="width">The width of the textbox.</param>
/// <param name="format">The format of the value.</param>
/// <param name="integerPositions">The integerpositions before the comma.</param>
/// <param name="decimalPlaces">The decimal places after the comma.</param>
/// <returns>Returns an object of type TextBox.</returns>
public TextBox CreateTextbox(MainViewModel viewmodel, string tablename, string sourceColumn, double leftPos, double topPos,
double width, string format="", int integerPositions=0, int decimalPlaces=0)
{
// Textbox is created.
TextBox textbox = new TextBox();
textbox.Width = width;
Canvas.SetLeft(textbox, leftPos);
Canvas.SetTop(textbox, topPos);
// Now the binding to the datasource is initialized.
Binding controlbinding = new Binding();
controlbinding.Source = viewmodel.ApplicationDataSet.Tables[tablename].DefaultView;
controlbinding.Path = new PropertyPath("[0][" + sourceColumn + "]");
if (!string.IsNullOrWhiteSpace(format))
{
controlbinding.StringFormat = format;
textbox.MaxLength = integerPositions + decimalPlaces + 1;
////controlbinding.ValidationRules = ???;
}
controlbinding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
textbox.SetBinding(TextBox.TextProperty, controlbinding);
return textbox;
}
YYYY
答案 0 :(得分:0)
您可以尝试创建例如一种看似类似的行为:
public class TextBoxNumericalOnlyBehavior : Behavior<Control>
{
private TextBox textBox;
public static readonly DependencyProperty MaxValueProperty =
DependencyProperty.Register("MaxValue", typeof(Double), typeof(TextBoxNumericalOnlyBehavior),
new FrameworkPropertyMetadata(Double.MaxValue));
public Double MaxValue
{
get
{
return (Double)base.GetValue(MaxValueProperty);
}
set
{
base.SetValue(MaxValueProperty, value);
}
}
public static readonly DependencyProperty MinValueProperty =
DependencyProperty.Register("MinValue", typeof(Double), typeof(TextBoxNumericalOnlyBehavior),
new FrameworkPropertyMetadata(Double.MinValue));
public Double MinValue
{
get
{
return (Double)base.GetValue(MinValueProperty);
}
set
{
base.SetValue(MinValueProperty, value);
}
}
public static readonly DependencyProperty RegularExpressionProperty =
DependencyProperty.Register("RegularExpression", typeof(string), typeof(TextBoxNumericalOnlyBehavior),
new FrameworkPropertyMetadata(".*"));
public string RegularExpression
{
get
{
return (string)base.GetValue(RegularExpressionProperty);
}
set
{
base.SetValue(RegularExpressionProperty, value);
}
}
protected override void OnAttached()
{
base.OnAttached();
AssociatedObject.Loaded += AssociatedObject_Loaded;
AssociatedObject.Unloaded += AssociatedObject_Unloaded;
AssociatedObject.PreviewKeyDown += AssociatedObject_PreviewKeyDown;
AssociatedObject.PreviewTextInput += AssociatedObject_PreviewTextInput;
DataObject.AddPastingHandler(AssociatedObject, OnPaste);
}
private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
{
// to do
}
private void AssociatedObject_Unloaded(object sender, RoutedEventArgs e)
{
// to do
}
private void AssociatedObject_PreviewKeyDown(object sender, KeyEventArgs e)
{
if (this.textBox != null)
{
if (e.Key == Key.Space || e.Key == Key.Delete)
{
e.Handled = true;
}
else if (e.Key == Key.Back)
{
e.Handled = !IsValid(string.Empty, false, true);
}
}
}
private void AssociatedObject_PreviewTextInput(object sender, TextCompositionEventArgs e)
{
if (this.textBox != null)
{
e.Handled = !IsValid(e.Text, false, false);
}
}
private void OnPaste(object sender, DataObjectPastingEventArgs e)
{
if (e.DataObject.GetDataPresent(DataFormats.Text))
{
string text = Convert.ToString(e.DataObject.GetData(DataFormats.Text));
if (!IsValid(text, true, false))
{
e.CancelCommand();
}
}
else
{
e.CancelCommand();
}
}
private bool IsValid(string text, bool paste, bool back)
{
if(this.textBox.Text == null)
{
return false;
}
int caretIndex = this.textBox.CaretIndex;
int selectionStart = this.textBox.SelectionStart;
int selectionLength = this.textBox.SelectionLength;
string newValue = string.Empty;
// on paste
if (paste && selectionLength > 0)
{
string tempValue = this.textBox.Text.Remove(selectionStart, selectionLength);
newValue = tempValue.Insert(caretIndex, text.Trim());
}
// on back
else if (back)
{
// check if textbox is empty
if (this.textBox.Text.Equals(string.Empty))
{
return true;
}
newValue = this.textBox.Text.Remove(selectionStart == 0 ? selectionStart : selectionStart - 1,
selectionLength == 0 ? 1 : selectionLength);
}
else
{
newValue = this.textBox.Text.Insert(caretIndex, text.Trim());
}
return IsInRange(newValue);
}
private bool IsInRange(string text)
{
Double result = 0;
if (text.Equals(string.Empty))
{
return true;
}
if (Regex.IsMatch(text, this.RegularExpression))
{
if (Double.TryParse(text, out result))
{
return result <= this.MaxValue && result >= this.MinValue;
}
}
return false;
}
}
和.xaml:
<i:Interaction.Behaviors>
<commonBehaviors:TextBoxNumericalOnlyBehavior MaxValue="99.99"
MinValue="0.00"
RegularExpression="^(\d{0,2})(\.\d{0,2})?$"/>
</i:Interaction.Behaviors>
常规exp:RegularExpression="^(\d{0,2})(\.\d{0,2})?$"/>
将仅允许00.00格式,但假设RegularExpression="^(\d{0,4})(\.\d{0,2})?$"/>
将允许0000.00。 Max和Min Values设置输入范围。