WPF 文本框不会触发依赖属性设置器

Posted

技术标签:

【中文标题】WPF 文本框不会触发依赖属性设置器【英文标题】:WPF textbox doesn't trigger dependency property setter 【发布时间】: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 一起工作吗?

【问题讨论】:

【参考方案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 来检查文本与正则表达式的匹配,它运行良好。

以上是关于WPF 文本框不会触发依赖属性设置器的主要内容,如果未能解决你的问题,请参考以下文章

WPF之TextBox和PasswordBox水印效果

使用 WPF 平滑文本动画(选取框)

设置DataContext后WPF依赖属性两种方式绑定不起作用[重复]

WPF中的依赖属性

在依赖属性 WPF 上使用绑定时出现问题 [重复]

1. 依赖项属性 简单理解