【问题标题】:How to reupdate Textbox validation by tabcontrol tabitem selection change如何通过 tabcontrol tabitem 选择更改重新更新文本框验证
【发布时间】:2017-07-21 09:14:58
【问题描述】:

在尝试将实体保存到数据库之前,我必须验证一些属性。

问题:

  1. Programmstart:tabitem1 中的文本框显示验证错误
  2. 用户选择:视图中的 Tabitem2
  3. 用户选择:视图中的 Tabitem1
  4. 空文本框的验证错误不再显示在 tabitem1 中。

异常行为:

如果用户更改所选的tabitem,每次都会显示验证错误。

使用的工具/框架:

  1. Prism 6.3(使用 Templatepack PrismUnity 的新项目
  2. Prism.Validation (https://github.com/mfe-/Prism.Validation)

问题:

  1. 为什么在不同的 tabitem 之间选择后 DataAnnoation 不再显示? ViewModel 属性 hasErrors 为 true。
  2. 如果用户再次选择了 tabitem1,我如何重新开始评估?

查看:

<Window x:Class="PrismUnityApp1TestValidation.Views.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:prism="http://prismlibrary.com/"
        prism:ViewModelLocator.AutoWireViewModel="True"
        Title="{Binding Title}" Height="350" Width="525">
    <StackPanel>
        <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />-->
        <TabControl>
        <TabItem>
         <TabItem.Content>
             <TextBox Height="50" Text="{Binding TestText, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBox>
         </TabItem.Content>
        </TabItem>
            <TabItem>
                <TabItem.Content>
                   <TextBlock Text="TabItem2"></TextBlock>
                </TabItem.Content>
            </TabItem>

        </TabControl>
    </StackPanel>
</Window>

视图模型:

using System.ComponentModel.DataAnnotations;
using Prism.Mvvm;
using Prism.Validation;

namespace PrismUnityApp1TestValidation.ViewModels
{
    public class MainWindowViewModel : ValidatableBindableBase
    {
        private string _title = "Prism Unity Application";
        public string Title
        {
            get { return _title; }
            set { SetProperty(ref _title, value); }
        }

        private string _testtext;
        [Required]
        public string TestText
        {
            get { return _testtext; }
            set { SetProperty(ref _testtext, value); }
        }


        public MainWindowViewModel()
        {

        }
    }
}

ValidatableBindableBase(NugetPackage Prism.Validation):

namespace Prism.Validation
{
    /// <summary>
    /// The IValidatableBindableBase interface was created to add validation support for model classes that contain validation rules.
    /// The default implementation of IValidatableBindableBase is the ValidatableBindableBase class, which contains the logic to run the validation rules of the
    /// instance of a model class and return the results of this validation as a list of properties' errors.
    /// </summary>
    // Documentation on validating user input is at http://go.microsoft.com/fwlink/?LinkID=288817&clcid=0x409
    public class ValidatableBindableBase : BindableBase, IValidatableBindableBase, INotifyDataErrorInfo
    {
        private readonly BindableValidator _bindableValidator;

        /// <summary>
        /// Initializes a new instance of the <see cref="ValidatableBindableBase"/> class.
        /// </summary>
        public ValidatableBindableBase()
        {
            _bindableValidator = new BindableValidator(this);
        }

        /// <summary>
        /// Gets or sets a value indicating whether this instance is validation enabled.
        /// </summary>
        /// <value>
        /// <c>true</c> if validation is enabled for this instance; otherwise, <c>false</c>.
        /// </value>
        public bool IsValidationEnabled
        {
            get { return _bindableValidator.IsValidationEnabled; }
            set { _bindableValidator.IsValidationEnabled = value; }
        }

        /// <summary>
        /// Returns the BindableValidator instance that has an indexer property.
        /// </summary>
        /// <value>
        /// The Bindable Validator Indexer property.
        /// </value>
        public BindableValidator Errors
        {
            get
            {
                return _bindableValidator;
            }
        }
        /// <summary>
        /// Gets a value that indicates whether the entity has validation errors.
        /// </summary>
        /// <value>
        /// <c>true</c> if this instance contains validation errors; otherwise, <c>false</c>.
        /// </value>
        public bool HasErrors
        {
            get
            {
                return !ValidateProperties();
            }
        }

        /// <summary>
        /// Occurs when the Errors collection changed because new errors were added or old errors were fixed.
        /// </summary>
        public event EventHandler<DataErrorsChangedEventArgs> ErrorsChanged
        {
            add { _bindableValidator.ErrorsChanged += value; }

            remove { _bindableValidator.ErrorsChanged -= value; }
        }

        /// <summary>
        /// Gets all errors.
        /// </summary>
        /// <returns> A ReadOnlyDictionary that's key is a property name and the value is a ReadOnlyCollection of the error strings.</returns>
        public ReadOnlyDictionary<string, ReadOnlyCollection<string>> GetAllErrors()
        {
            return _bindableValidator.GetAllErrors();
        }

        /// <summary>
        /// Validates the properties of the current instance.
        /// </summary>
        /// <returns>
        /// Returns <c>true</c> if all properties pass the validation rules; otherwise, false.
        /// </returns>
        public bool ValidateProperties()
        {
            return _bindableValidator.ValidateProperties();
        }

        /// <summary>
        /// Validates a single property with the given name of the current instance.
        /// </summary>
        /// <param name="propertyName">The property to be validated.</param>
        /// <returns>Returns <c>true</c> if the property passes the validation rules; otherwise, false.</returns>
        public bool ValidateProperty(string propertyName)
        {
            return !_bindableValidator.IsValidationEnabled // don't fail if validation is disabled
                || _bindableValidator.ValidateProperty(propertyName);
        }

        /// <summary>
        /// Sets the error collection of this instance.
        /// </summary>
        /// <param name="entityErrors">The entity errors.</param>
        public void SetAllErrors(IDictionary<string, ReadOnlyCollection<string>> entityErrors)
        {
            _bindableValidator.SetAllErrors(entityErrors);
        }

        /// <summary>
        /// Checks if a property already matches a desired value. Sets the property and
        /// notifies listeners only when necessary. We are overriding this property to ensure that the SetProperty and the ValidateProperty methods are fired in a
        /// deterministic way.
        /// </summary>
        /// <typeparam name="T">Type of the property.</typeparam>
        /// <param name="storage">Reference to a property with both getter and setter.</param>
        /// <param name="value">Desired value for the property.</param>
        /// <param name="propertyName">Name of the property used to notify listeners. This
        /// value is optional and can be provided automatically when invoked from compilers that
        /// support CallerMemberName.</param>
        /// <returns>
        /// True if the value was changed, false if the existing value matched the
        /// desired value.
        /// </returns>
        protected override bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            var result = base.SetProperty(ref storage, value, propertyName);

            if (result && !string.IsNullOrEmpty(propertyName))
            {
                if (_bindableValidator.IsValidationEnabled)
                {
                    _bindableValidator.ValidateProperty(propertyName);
                }
            }
            return result;
        }
        /// <summary>
        /// Gets the validation errors for a specified property or for the entire entity.
        /// </summary>
        /// <param name="propertyName">The name of the property to retrieve validation errors for; or null or Empty, to retrieve entity-level errors.</param>
        /// <returns>The validation errors for the property or entity.</returns>
        public IEnumerable GetErrors(string propertyName)
        {
            if (HasErrors==false)
            {
                return Enumerable.Empty<String>();
            }
            return _bindableValidator[propertyName];
        }
    }
}

【问题讨论】:

    标签: c# wpf prism


    【解决方案1】:

    我在这里找到了解决方案:

    https://social.msdn.microsoft.com/Forums/vstudio/en-US/fb50537c-feec-42dc-8439-dcf78ef8951a/validation-error-and-tab-control?forum=wpf

    我按照帖子中的说明更改了我的视图。

    查看:

    <Window x:Class="PrismUnityApp1TestValidation.Views.MainWindow"
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:prism="http://prismlibrary.com/"
            prism:ViewModelLocator.AutoWireViewModel="True"
            Title="{Binding Title}" Height="350" Width="525">
        <StackPanel>
            <!--<ContentControl prism:RegionManager.RegionName="ContentRegion" />-->
            <TabControl>
            <TabItem IsSelected="{Binding TabItem1Selected}">
             <TabItem.Content>
                 <AdornerDecorator>
                     <TextBox Height="50" Text="{Binding TestText, ValidatesOnDataErrors=True, NotifyOnValidationError=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"></TextBox>
                        </AdornerDecorator>
    
             </TabItem.Content>
            </TabItem>
                <TabItem>
                    <TabItem.Content>
                       <TextBlock Text="TabItem2"></TextBlock>
                    </TabItem.Content>
                </TabItem>
    
            </TabControl>
        </StackPanel>
    </Window>
    

    【讨论】:

      猜你喜欢
      • 2020-04-05
      • 2010-12-20
      • 2018-06-21
      • 1970-01-01
      • 2013-03-03
      • 1970-01-01
      • 1970-01-01
      • 1970-01-01
      • 2014-04-12
      相关资源
      最近更新 更多