wpf 在绑定更新的绑定源中触发 PropertyChanged 事件
wpf fire PropertyChanged event in binding source that binding gets updated
我正在尝试制作一些具有验证功能的 CustomControl 文本框。
(例如只有数字的文本框或邮政编码文本框等)
它应该在一个.dll 库文件中实现。
我的项目包含一个用于文本框的 CustomControl,一个处理验证的 class,
和一个应该在 TextBlock 中显示错误消息的 ErrMsgGui CustomControl
(例如:只允许输入数字...)
我的问题是,当调用验证 class 中的方法时,我没有更新 TextBlock 文本
有没有办法触发 PropertyChangeEvent 来更新验证中的文本块文本 class?
(我对 wpf 很陌生)
Generic.xaml:
<Style TargetType="{x:Type local:NumTb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NumTb}">
<TextBox Background="{TemplateBinding Background}" Text="{Binding Source={StaticResource NumTbVm}, Path=NumTbText, UpdateSourceTrigger=PropertyChanged}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ErrMsgGui}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ErrMsgGui}">
<TextBlock Text="{ Binding Source={StaticResource val}, Path=ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Validations.cs:
private const string ONLY_NUMBERS_REGEX = @"^[0-9]+$"; //Nur Zahlen
private string _ErrMsgGuiText;
public string ErrMsgGuiText
{
get { return _ErrMsgGuiText; }
set
{
_ErrMsgGuiText = value;
Debug.Print("QueryText: " + value);
OnPropertyChanged("ErrMsgGuiText");
}
}
public object[] onlyNumbers(string s2c, bool output)
{
object[] objRes = new object[2];
bool result = true;
string errMsg = "";
Regex regex = new Regex(ONLY_NUMBERS_REGEX);
if (s2c != null && s2c != "" && !regex.IsMatch(s2c))
{
result = false;
errMsg = "Nur Zahlen sind zulässig";
}
objRes[0] = result;
objRes[1] = errMsg;
if (output == true)
{
ErrMsgGuiText = errMsg;
}
return objRes;
}
public void onlyNumbers(string s2c)
{
onlyNumbers(s2c, true);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
NumTbViewModel.cs:
Validations val = null;
public NumTbViewModel()
{
val = new Validations();
}
private string _NumTbText;
public string NumTbText
{
get { return _NumTbText; }
set
{
_NumTbText = value;
this.OnPropertyChanged("NumTbText");
val.onlyNumbers(_NumTbText);
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
看起来 TextBlock 源正在查看验证的静态资源 class,而在您的 NumTbViewModel 中调用的验证与静态资源不同。一种解决方案是将 属性 添加到 NumTbViewModel.cs 并将您的绑定指向该 属性,以便验证 class 实例将相同。在 NumTbViewModel.cs 添加:
Validations _val;
public Validations Val
{
get { return _val; }
set
{
_val = value;
this.OnPropertyChanged("Val");
}
}
在 TextBlock 上的 xaml 绑定中更改源和路径:
<TextBlock Text="{ Binding Source={StaticResource NumTbVm}, Path=Val.ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
另一种方式:
您还可以在像这样定义静态资源时设置 NumTbViewModel 的 Val 属性:
<local:Validations x:Key="val" />
<local:NumTbViewModel x:Key="NumTbVm" Val="{StaticResource val}" />
这样做,您可以像原来那样保留绑定。
我正在尝试制作一些具有验证功能的 CustomControl 文本框。 (例如只有数字的文本框或邮政编码文本框等) 它应该在一个.dll 库文件中实现。
我的项目包含一个用于文本框的 CustomControl,一个处理验证的 class, 和一个应该在 TextBlock 中显示错误消息的 ErrMsgGui CustomControl (例如:只允许输入数字...)
我的问题是,当调用验证 class 中的方法时,我没有更新 TextBlock 文本
有没有办法触发 PropertyChangeEvent 来更新验证中的文本块文本 class?
(我对 wpf 很陌生)
Generic.xaml:
<Style TargetType="{x:Type local:NumTb}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:NumTb}">
<TextBox Background="{TemplateBinding Background}" Text="{Binding Source={StaticResource NumTbVm}, Path=NumTbText, UpdateSourceTrigger=PropertyChanged}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
<Style TargetType="{x:Type local:ErrMsgGui}">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="{x:Type local:ErrMsgGui}">
<TextBlock Text="{ Binding Source={StaticResource val}, Path=ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
Validations.cs:
private const string ONLY_NUMBERS_REGEX = @"^[0-9]+$"; //Nur Zahlen
private string _ErrMsgGuiText;
public string ErrMsgGuiText
{
get { return _ErrMsgGuiText; }
set
{
_ErrMsgGuiText = value;
Debug.Print("QueryText: " + value);
OnPropertyChanged("ErrMsgGuiText");
}
}
public object[] onlyNumbers(string s2c, bool output)
{
object[] objRes = new object[2];
bool result = true;
string errMsg = "";
Regex regex = new Regex(ONLY_NUMBERS_REGEX);
if (s2c != null && s2c != "" && !regex.IsMatch(s2c))
{
result = false;
errMsg = "Nur Zahlen sind zulässig";
}
objRes[0] = result;
objRes[1] = errMsg;
if (output == true)
{
ErrMsgGuiText = errMsg;
}
return objRes;
}
public void onlyNumbers(string s2c)
{
onlyNumbers(s2c, true);
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
NumTbViewModel.cs:
Validations val = null;
public NumTbViewModel()
{
val = new Validations();
}
private string _NumTbText;
public string NumTbText
{
get { return _NumTbText; }
set
{
_NumTbText = value;
this.OnPropertyChanged("NumTbText");
val.onlyNumbers(_NumTbText);
}
}
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
protected void OnPropertyChanged(string prop)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(prop));
}
}
看起来 TextBlock 源正在查看验证的静态资源 class,而在您的 NumTbViewModel 中调用的验证与静态资源不同。一种解决方案是将 属性 添加到 NumTbViewModel.cs 并将您的绑定指向该 属性,以便验证 class 实例将相同。在 NumTbViewModel.cs 添加:
Validations _val;
public Validations Val
{
get { return _val; }
set
{
_val = value;
this.OnPropertyChanged("Val");
}
}
在 TextBlock 上的 xaml 绑定中更改源和路径:
<TextBlock Text="{ Binding Source={StaticResource NumTbVm}, Path=Val.ErrMsgGuiText, UpdateSourceTrigger=PropertyChanged}" Background="{TemplateBinding Background}"/>
另一种方式: 您还可以在像这样定义静态资源时设置 NumTbViewModel 的 Val 属性:
<local:Validations x:Key="val" />
<local:NumTbViewModel x:Key="NumTbVm" Val="{StaticResource val}" />
这样做,您可以像原来那样保留绑定。