属性更改时不将值传回文本框的问题
本文关键字:文本 回文 问题 值传 属性 | 更新日期: 2023-09-27 17:54:35
我正在研究一个WPF应用程序,我有一个文本框绑定(双向)到我的视图模型中的属性。
我试图防止用户在这个文本框中输入超过100个字符(这是数据库将存储的最大值),所以我写了这个。
public abstract class AppBaseViewModel : ViewModelBase
{
private String _text;
public String Text
{
get { return _text; }
set
{
_text = CheckTextLength(value, _text);
OnPropertyChanged("Text");
}
}
private string CheckTextLength(string value, string text)
{
if (value.Length < 100)
{
return value;
}
else
{
return text;
}
}
}
所有这些代码似乎都是将前100个字符保存到字段中,但它仍然允许用户继续输入超过100个字符…我猜这是因为字段值没有被传递回文本框。
我不明白为什么这不起作用,因为我在不同的应用程序中使用MVVM Light的RaisePropertyChange()做了类似的事情。
值得注意的是,我无法访问文本框的设计器,因此无法将。net文本框属性设置为最大长度。
编辑:只是为了澄清,我不能查看或编辑xaml,因为有些人建议我没有访问xaml文件(我知道,这是愚蠢的)。默认情况下,我们使用的所有绑定都是双向的
你试过使用TextBox吗?最大长度?
<TextBox MaxLength="100"/>
获取或设置可手动输入文本框的最大字符数。
如果不能访问XAML,最终访问XAML,而不是解析和验证数组的长度,并在这里和那里使用子字符串。至少对于这个简单的问题,我会这样做,或者让设计师添加一小段代码。
更新1
public static T GetChildOfType<T>(DependencyObject depObj) where T : DependencyObject
{
if (depObj == null) return null;
for (int i = 0; i < VisualTreeHelper.GetChildrenCount(depObj); i++)
{
var child = VisualTreeHelper.GetChild(depObj, i);
var result = (child as T) ?? GetChildOfType<T>(child);
if (result != null) return result;
}
return null;
}
获取子节点并设置它的MaxLength。这只是对View的一个轻微修改,所以它不会影响MVVM模式。
OK。我一点也不确定我是否为此感到自豪,但我把它作为一种选择。
你可以通过给所有的 TextBox 应用一个通用的Style来改变TextBox的Text属性的UpdateSourceTrigger。这只会在很奇怪的情况下才可行,但这个问题本身有点不寻常。
XAML后台代码://I'm using MVVM Light here - you need to be able to find an instance
//of your AppBaseViewModel somehow.
private ViewModelLocator _locator;
//View codebehind constructor, may need to change names as appropriate
public AppBaseView()
{
InitializeComponent();
//MVVM Light again
_locator = new ViewModelLocator();
//Create the binding
Binding binding = new Binding();
//Source = The instance of your ViewModel
binding.Source = _locator.AppBaseViewModel ;
binding.Path = new PropertyPath("Text");
binding.Mode = BindingMode.TwoWay;
binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged;
//Create a Style with no Key - this will apply to *all* TextBoxes
//without their own explicit Style set.
Style style = new Style(typeof(TextBox));
style.Setters.Add(new Setter(TextBox.TextProperty, binding));
//Add the Style to the XAML's Resources:
Resources.Add(typeof(TextBox), style);
}
如果视图当前正在尝试更改属性本身,则不会侦听PropertyChanged通知。
唯一想到的是在检测到不满足约束时启动一个额外延迟的PropertyChanged通知…
private string CheckTextLength(string value, string text)
{
if (value.Length < 100)
{
return value;
}
else
{
MyDispatcher.BeginInvoke(new Action(() =>
OnPropertyChanged("Text")),
DispatcherPriority.Loaded);
return text;
}
}
不能尝试代码,如果它不能立即构建,很抱歉。例如,MyDispatcher
可以是您的Application.Current.Dispatcher
。
xaml视图/绑定仅在文本框失去焦点时更新。如果输入的文本为<100,则设置该值,否则设置_text。这意味着最初_text没有值,因此在if语句为false时将设置为null。我也建议你使用RaisePropertyChanged();当在属性内部使用时,不需要参数