C# 属性更改时未将值传回文本框的属性问题

C# 属性更改时未将值传回文本框的属性问题,c#,.net,wpf,mvvm,C#,.net,Wpf,Mvvm,我正在处理一个WPF应用程序,我的视图模型中有一个绑定到属性的文本框(双向) 我试图阻止用户在这个文本框中输入超过100个字符(这是数据库将存储的最大字符数),所以我写了这个 public abstract class AppBaseViewModel : ViewModelBase { private String _text; public String Text { get { return _text; } set

我正在处理一个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; 
        }
    }
}  
公共抽象类AppBaseViewModel:ViewModelBase { 私有字符串_文本; 公共字符串文本 { 获取{return\u text;} 设置 { _text=CheckTextLength(值,_text); OnPropertyChanged(“文本”); } } 私有字符串CheckTextLength(字符串值、字符串文本) { 如果(值。长度<100) { 返回值; } 其他的 { 返回文本; } } } 所有这些代码似乎只是将前100个字符保存到字段中,但它仍然允许用户继续键入超过100个字符。。。我猜这是因为字段值没有被传递回文本框

我不明白为什么这不起作用,因为我在另一个应用程序中使用MVVM Light的RaisePropertyChange()做了类似的事情

值得注意的是,我无法访问textbox的设计器,因此无法将.Net textbox属性设置为最大长度


编辑:为了澄清,我不能查看或编辑xaml,因为我没有访问xaml文件的权限(我知道,这很愚蠢)。默认情况下,我们使用的所有绑定都是双向的

您尝试过TextBox.MaxLength吗

<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;
    }
public static T GetChildOfType(DependencyObject depObj),其中T:DependencyObject
{
if(depObj==null)返回null;
for(int i=0;i

去找那个孩子,设置它的最大长度。这只是对视图的轻微修改,因此不会影响MVVM模式。

您是否尝试过使用TextBox.MaxLength

<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;
    }
public static T GetChildOfType(DependencyObject depObj),其中T:DependencyObject
{
if(depObj==null)返回null;
for(int i=0;i

去找那个孩子,设置它的最大长度。这只是对视图的轻微修改,因此不会影响MVVM模式。

确定。我一点也不确定我是否为此感到自豪,但我将它作为一种替代方案

通过对所有文本框应用通用样式,可以更改文本框文本属性的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);
}

嗯。我一点也不确定我是否为此感到自豪,但我将它作为一种替代方案

通过对所有文本框应用通用样式,可以更改文本框文本属性的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; 
    }
}
私有字符串CheckTextLength(字符串值,字符串文本)
{
如果(值。长度<100)
{
返回值;
}
其他的
{
MyDispatcher.BeginInvoke(新操作(()=>
OnPropertyChanged(“文本”),
DispatcherPriority.Loaded);
返回文本;
}
}

无法尝试该代码,因此,如果它无法完全构建,则表示抱歉<例如,code>MyDispatcher
可以是您的
应用程序.Current.Dispatcher

如果视图当前正在尝试更改属性本身,则该视图将不会侦听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; 
    }
}
私有字符串CheckTextLength(字符串值,字符串文本)
{
如果(值。长度<100)
{
返回值;
}
其他的
{
MyDispatcher.BeginInvoke(新操作(()=>
OnPropertyChanged(“文本”),
DispatcherPriority.Loaded);
返回文本;
}
}

无法尝试该代码,因此,如果它无法完全构建,则表示抱歉<例如,code>MyDispatcher
可以是您的
应用程序.Current.Dispatcher

xaml视图/绑定仅在文本框失去焦点时更新。如果输入的文本是xaml视图/仅当文本框失去焦点时才更新绑定。如果输入的文本是带绑定的XAML。您是否将绑定模式设置为双向?您所说的“无法设置.Net textbox pro”是什么意思