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 文本框不会触发依赖属性设置器的主要内容,如果未能解决你的问题,请参考以下文章