将所有绑定的文本框设置为修剪

时间:2019-06-16 14:35:45

标签: c# wpf mvvm

我正在使用MVVM创建WPF应用程序。我想这样做,以便默认情况下应用程序中的所有文本框都会修剪文本。

我尝试遵循答案here

我设法通过NuGet添加System.Windows.Interactivty引用。我在一个行为文件夹中创建了一个UserControl,并复制了提供的代码。但是Visual Studio无法找到合适的方法来覆盖,并且AssociatedObject不存在。

在XAML中,它不喜欢<local:TrimTextBoxBehavior />xmlns:local="clr-namespace:StaffApp;assembly=mscorlib"xmlns:local="clr-namespace:StaffApp.Behaviors;assembly=mscorlib"


我尝试了另一种修剪模型中所有绑定属性的设置器的方法

例如public string MiddleNames { get => _middleNames; set => _middleNames = value.Trim(); }

但是我不喜欢对每个属性都必须这样做,并且当文本框为XAML表单中定义的null时,这会引起问题:

<Label Width="100" Content="Middle name(s)" />
<TextBox Text="{Binding Employee.MiddleNames, TargetNullValue=''}" />

2 个答案:

答案 0 :(得分:1)

您可以尝试使用转换器。这样,您只需要将转换器添加到文本框的绑定即可。

// Property in the View Model
public string Text { get;set; }

// Converter class
public class TrimTextConverter : IValueConverter {
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture) {
        if (!string.IsNullOrEmpty((string)value)) {
            return ((string)value).Trim();
        }
        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) {
        return value;
    }
}
<!--In the xaml file-->

<!--Reference to the converter namespace-->
xmlns:converter="clr-namespace:namespace-where-converter-is-located"

<!--Adding Converter To Resource Dictionary-->
<ResourceDictionary>
    <converter:TrimTextConverter x:Key="TrimTextConverter"/>
</ResourceDictionary>

<!--TextBox-->
<TextBox Grid.Row="4" Text="{Binding Text, Converter={StaticResource TrimTextConverter}">

答案 1 :(得分:1)

您需要一个ValueConverter或通过Style应用于所有TextBox控件的附加行为。第三种选择是扩展TextBox并覆盖TextBoxBase.OnTextChanged(TextChangedEventArgs)

TextTrimBehavior

public class TextTrimBehavior : DependencyObject
{
  #region IsEnabled attached property

  public static readonly DependencyProperty IsEnabledProperty = DependencyProperty.RegisterAttached(
    "IsEnabled", typeof(bool), typeof(TextTrimBehavior), new PropertyMetadata(false, TextTrimBehavior.OnAttached));

  public static void SetIsEnabled(DependencyObject attachingElement, bool value)
  {
    attachingElement.SetValue(TextTrimBehavior.IsEnabledProperty, value);
  }

  public static bool GetIsEnabled(DependencyObject attachingElement)
  {
    return (bool) attachingElement.GetValue(TextTrimBehavior.IsEnabledProperty);
  }

  #endregion

  private static void OnAttached(DependencyObject d, DependencyPropertyChangedEventArgs e)
  {
    if (!(d is TextBox attachedTextBox))
    {
      return;
    }

    if ((bool) e.NewValue)
    {
      attachedTextBox.LostFocus += TextTrimBehavior.TrimText;
    }
    else
    {
      attachedTextBox.LostFocus -= TextTrimBehavior.TrimText;
    }
  }

  private static void TrimText(object sender, RoutedEventArgs e)
  {
    if (sender is TextBox textBox)
    {
      textBox.Text = textBox.Text.Trim();
    }
  }
}

TextBox样式:

<Style TargetType="TextBox">
    <Setter Property="behaviors:TextTrimBehavior.IsEnabled" 
            Value="True" /> 
</Style> 

由于Style没有键,它将隐式应用于范围内的所有TextBox控件。要使样式变为全局样式,您必须将其放入App.xaml ResourceDictionary

使用Style.BasedOn扩展隐式样式:

<Style x:Key="ExplicitStyle" TargetType="TextBox" 
       BasedOn="{StaticResource {x:Type TextBox}}">
    <Setter Property="Background"
            Value="YellowGreen" />
</Style>