【问题标题】:WPF textbox doesn't trigger dependency property setterWPF 文本框不会触发依赖属性设置器
【发布时间】:2021-11-08 08:08:16
【问题描述】:

我正在尝试基于 TextBox 创建一个 UserControl,当它失去焦点时,如果它与 Regex 不匹配,则 Text 将被擦除。

我的问题如下:我已经在我的 UserControl 中将 TextBox 的 Text 属性与名为 Text 的 DependencyProperty 绑定了,但是当我在 TextBox 中写入错误的 Text 然后使其失去焦点时,它不会做任何事情.

用户控件 XAML:

<Grid>
        <TextBox VerticalContentAlignment="Center" Text="{Binding Text, UpdateSourceTrigger=LostFocus, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" FontFamily="{Binding FontFamily, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}"  FontSize="{Binding FontSize, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=UserControl}}" />
</Grid>

CS 后面的用户控制代码(带有 DependencyProperty):

// Text of the FormatBox
public static readonly DependencyProperty CS_EXAMPLETEXT_PROPERTY = DependencyProperty.Register(nameof(Text), typeof(String), typeof(FormatBox));
public string Text
{
      get { return (string)GetValue(CS_EXAMPLETEXT_PROPERTY); }
      set {
          if (Regex.IsMatch(value ?? "", RegexString ?? "")) SetValue(CS_EXAMPLETEXT_PROPERTY, value);
          else SetValue(CS_EXAMPLETEXT_PROPERTY, "");
      }
}

MainWindows XAML:

<!-- Test FormatBox -->
<controls:FormatBox Grid.Row="3" FontFamily="Calibri" FontSize="16" RegexString="^(?:[0-9]{1,3}\\.){3}[0-9]{1,3}$" />

但是,如果我尝试对普通属性做同样的事情并实现 INotifyPropertyChanged,它就像一个魅力。

CS后面的UserControl代码(具有普通属性):

#region INotifyPropertyChanged

public event PropertyChangedEventHandler PropertyChanged;
private Dictionary<string, object> _propertyValues = new Dictionary<string, object>();

protected T GetProperty<T>([CallerMemberName] string propertyName = null)
{
        if (_propertyValues.ContainsKey(propertyName)) return (T)_propertyValues[propertyName];
        return default(T);
}

protected bool SetProperty<T>(T newValue, [CallerMemberName] string propertyName = null)
{
        T current = GetProperty<T>(propertyName);
        if (!EqualityComparer<T>.Default.Equals(current, newValue))
        {
            _propertyValues[propertyName] = newValue;
            if (PropertyChanged != null)
            {
                PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
            }
            return true;
         }
         return false;
}

#endregion

// Text of the FormatBox
public string Text
{
        get { return GetProperty<string>(); }
        set {
            if (Regex.IsMatch(value ?? "", RegexString ?? "")) SetProperty<string>(value);
            else SetProperty<string>("");
        }
}

你能帮我让它与 DependencyProperty 一起工作吗?

【问题讨论】:

    标签: c# wpf xaml data-binding dependency-properties


    【解决方案1】:

    希望我能正确理解您的问题。通过“它什么都不做”,如果您的意思是为什么您包含在 Dependency 属性的 .Net Wrapper 属性中的条件代码未执行,请注意 .Net Wrapper 属性会在运行时被绕过。

    您可以在Xaml Loading and Dependency Properties 上阅读更多信息。

    回到您需要实现的自定义逻辑,这正是CoerceValueCallback 存在的原因。CoerceValueCallback 作为Property Value Evaluation 中的最后一步之一执行,非常适合对值进行此类更正。

    例如,

    
    public static readonly DependencyProperty TextProperty =
         DependencyProperty.Register(
             nameof(Text),
             typeof(string), 
             typeof(SampleControl),
             new PropertyMetadata(
                 string.Empty, null, new CoerceValueCallback(OnTextValueCoerce)));
    
    private static object OnTextValueCoerce(DependencyObject d, object baseValue)
    {
      if(baseValue is string val && d is SampleControl ctrl)
      {
        if (Regex.IsMatch(val ?? string.Empty,  ctrl.RegexString ?? string.Empty)) 
              return baseValue;
        else 
              return string.Empty;
      }
    
      return string.Empty;
    }
    

    【讨论】:

    • 非常感谢您理解它写的,抱歉错过了公式。我已经在我的 DependancyProperty 上实现了 CoerceValueCallback 来检查文本与正则表达式的匹配,它运行良好。
    猜你喜欢
    • 2011-08-04
    • 1970-01-01
    • 1970-01-01
    • 2017-05-04
    • 2011-02-13
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多