Skip to content
  • Categories
  • Recent
  • Tags
  • Popular
  • World
  • Users
  • Groups
Skins
  • Light
  • Cerulean
  • Cosmo
  • Flatly
  • Journal
  • Litera
  • Lumen
  • Lux
  • Materia
  • Minty
  • Morph
  • Pulse
  • Sandstone
  • Simplex
  • Sketchy
  • Spacelab
  • United
  • Yeti
  • Zephyr
  • Dark
  • Cyborg
  • Darkly
  • Quartz
  • Slate
  • Solar
  • Superhero
  • Vapor

  • Default (No Skin)
  • No Skin
Collapse
Code Project
  1. Home
  2. General Programming
  3. WPF
  4. UI Validation Problem

UI Validation Problem

Scheduled Pinned Locked Moved WPF
helpdesignquestion
8 Posts 3 Posters 28 Views 1 Watching
  • Oldest to Newest
  • Newest to Oldest
  • Most Votes
Reply
  • Reply as topic
Log in to reply
This topic has been deleted. Only users with topic management privileges can see it.
  • K Offline
    K Offline
    Kevin Marois
    wrote on last edited by
    #1

    I am implementing INotifyDataErrorInfo. Here's my base ViewModel

    public class \_ViewModelBase : BindableBase, INotifyDataErrorInfo
    {
        #region Events
        public event EventHandler ErrorsChanged;
        #endregion
    
        #region Private Fields
        public readonly Dictionary\> \_validationErrors = new Dictionary\>();
        #endregion
    
        #region Properties
        public bool HasErrors => \_validationErrors.Any();
        #endregion
    
        #region Public Methods
        public IEnumerable GetErrors(string propertyName)
        {
            return \_validationErrors.ContainsKey(propertyName) ? \_validationErrors\[propertyName\] : null;
        }
        #endregion
    
        #region Protected Methods
        protected void AddError(string propertyName, string error)
        {
            if (!\_validationErrors.ContainsKey(propertyName))
            {
                \_validationErrors\[propertyName\] = new List();
            }
    
            if (!\_validationErrors\[propertyName\].Contains(error))
            {
                \_validationErrors\[propertyName\].Add(error);
                RaiseErrorsChanged(propertyName);
            }
        }
    
        protected void ClearErrors(string propertyName)
        {
            if (\_validationErrors.ContainsKey(propertyName))
            {
                \_validationErrors.Remove(propertyName);
                {
                    RaiseErrorsChanged(propertyName);
                }
            }
        }
        #endregion
    
        #region Private Methods
        private void RaiseErrorsChanged(string propertyName)
        {
            ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
        }
        #endregion
    }
    

    Here's my CustomerView

    Richard DeemingR L 2 Replies Last reply
    0
    • K Kevin Marois

      I am implementing INotifyDataErrorInfo. Here's my base ViewModel

      public class \_ViewModelBase : BindableBase, INotifyDataErrorInfo
      {
          #region Events
          public event EventHandler ErrorsChanged;
          #endregion
      
          #region Private Fields
          public readonly Dictionary\> \_validationErrors = new Dictionary\>();
          #endregion
      
          #region Properties
          public bool HasErrors => \_validationErrors.Any();
          #endregion
      
          #region Public Methods
          public IEnumerable GetErrors(string propertyName)
          {
              return \_validationErrors.ContainsKey(propertyName) ? \_validationErrors\[propertyName\] : null;
          }
          #endregion
      
          #region Protected Methods
          protected void AddError(string propertyName, string error)
          {
              if (!\_validationErrors.ContainsKey(propertyName))
              {
                  \_validationErrors\[propertyName\] = new List();
              }
      
              if (!\_validationErrors\[propertyName\].Contains(error))
              {
                  \_validationErrors\[propertyName\].Add(error);
                  RaiseErrorsChanged(propertyName);
              }
          }
      
          protected void ClearErrors(string propertyName)
          {
              if (\_validationErrors.ContainsKey(propertyName))
              {
                  \_validationErrors.Remove(propertyName);
                  {
                      RaiseErrorsChanged(propertyName);
                  }
              }
          }
          #endregion
      
          #region Private Methods
          private void RaiseErrorsChanged(string propertyName)
          {
              ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
          }
          #endregion
      }
      

      Here's my CustomerView

      Richard DeemingR Offline
      Richard DeemingR Offline
      Richard Deeming
      wrote on last edited by
      #2

      That makes no sense - both nameof(Customer.CustomerName) and nameof(CustomerName) will compile to the constant string "CustomerName". Are you sure that the view-model property is spelled correctly?


      "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

      "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

      K 1 Reply Last reply
      0
      • Richard DeemingR Richard Deeming

        That makes no sense - both nameof(Customer.CustomerName) and nameof(CustomerName) will compile to the constant string "CustomerName". Are you sure that the view-model property is spelled correctly?


        "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

        K Offline
        K Offline
        Kevin Marois
        wrote on last edited by
        #3

        OK, so I'm not really sure what the problem is here:

        private void Validate()
        {
        ClearErrors("CustomerName");

        if (string.IsNullOrWhiteSpace(Customer.CustomerName))
        {
            AddError("CustomerName", "The Customer Name cannot be empty.");
        }
        

        }

        The TextBox is bound to Customer.CustomerName. When I remove the text, the error is added, but I don't see anything. I'm guessing I'm not doing this right.

        In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.

        Richard DeemingR 1 Reply Last reply
        0
        • K Kevin Marois

          I am implementing INotifyDataErrorInfo. Here's my base ViewModel

          public class \_ViewModelBase : BindableBase, INotifyDataErrorInfo
          {
              #region Events
              public event EventHandler ErrorsChanged;
              #endregion
          
              #region Private Fields
              public readonly Dictionary\> \_validationErrors = new Dictionary\>();
              #endregion
          
              #region Properties
              public bool HasErrors => \_validationErrors.Any();
              #endregion
          
              #region Public Methods
              public IEnumerable GetErrors(string propertyName)
              {
                  return \_validationErrors.ContainsKey(propertyName) ? \_validationErrors\[propertyName\] : null;
              }
              #endregion
          
              #region Protected Methods
              protected void AddError(string propertyName, string error)
              {
                  if (!\_validationErrors.ContainsKey(propertyName))
                  {
                      \_validationErrors\[propertyName\] = new List();
                  }
          
                  if (!\_validationErrors\[propertyName\].Contains(error))
                  {
                      \_validationErrors\[propertyName\].Add(error);
                      RaiseErrorsChanged(propertyName);
                  }
              }
          
              protected void ClearErrors(string propertyName)
              {
                  if (\_validationErrors.ContainsKey(propertyName))
                  {
                      \_validationErrors.Remove(propertyName);
                      {
                          RaiseErrorsChanged(propertyName);
                      }
                  }
              }
              #endregion
          
              #region Private Methods
              private void RaiseErrorsChanged(string propertyName)
              {
                  ErrorsChanged?.Invoke(this, new DataErrorsChangedEventArgs(propertyName));
              }
              #endregion
          }
          

          Here's my CustomerView

          L Offline
          L Offline
          Lost User
          wrote on last edited by
          #4

          Being "in error" is the state of the object in question; not a flag or entry in a list. That's transaction oriented versus "online". My "HasErrors" runs all the "validations" on the object and returns true or false anytime it is called (e.g. before saving). No "error lists" to clear etc. You can also retrieve all errors (to show only the first, for example, to avoid overloading thee user). At the same time, all the textboxes in error are "red lined" as expected.

          "Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I

          K 1 Reply Last reply
          0
          • L Lost User

            Being "in error" is the state of the object in question; not a flag or entry in a list. That's transaction oriented versus "online". My "HasErrors" runs all the "validations" on the object and returns true or false anytime it is called (e.g. before saving). No "error lists" to clear etc. You can also retrieve all errors (to show only the first, for example, to avoid overloading thee user). At the same time, all the textboxes in error are "red lined" as expected.

            "Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I

            K Offline
            K Offline
            Kevin Marois
            wrote on last edited by
            #5

            See my latest reply to Richard

            In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.

            L 1 Reply Last reply
            0
            • K Kevin Marois

              See my latest reply to Richard

              In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.

              L Offline
              L Offline
              Lost User
              wrote on last edited by
              #6

              I think you have a "ValidatesOn..." mismatch. [https://stackoverflow.com/questions/17254847/what-is-the-difference-between-validatesonnotifydataerrors-and-validatesondataer\](https://stackoverflow.com/questions/17254847/what-is-the-difference-between-validatesonnotifydataerrors-and-validatesondataer)

              "Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I

              K 1 Reply Last reply
              0
              • K Kevin Marois

                OK, so I'm not really sure what the problem is here:

                private void Validate()
                {
                ClearErrors("CustomerName");

                if (string.IsNullOrWhiteSpace(Customer.CustomerName))
                {
                    AddError("CustomerName", "The Customer Name cannot be empty.");
                }
                

                }

                The TextBox is bound to Customer.CustomerName. When I remove the text, the error is added, but I don't see anything. I'm guessing I'm not doing this right.

                In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.

                Richard DeemingR Offline
                Richard DeemingR Offline
                Richard Deeming
                wrote on last edited by
                #7

                The errors don't match the property you're binding to. Try using:

                const string propertyName = $"{nameof(Customer)}.{nameof(Customer.CustomerName)}";

                ClearErrors(propertyName);

                f (string.IsNullOrWhiteSpace(Customer.CustomerName))
                {
                AddError(propertyName, "The Customer Name cannot be empty.");
                }


                "These people looked deep within my soul and assigned me a number based on the order in which I joined." - Homer

                "These people looked deep within my soul and assigned me a number based on the order in which I joined" - Homer

                1 Reply Last reply
                0
                • L Lost User

                  I think you have a "ValidatesOn..." mismatch. [https://stackoverflow.com/questions/17254847/what-is-the-difference-between-validatesonnotifydataerrors-and-validatesondataer\](https://stackoverflow.com/questions/17254847/what-is-the-difference-between-validatesonnotifydataerrors-and-validatesondataer)

                  "Before entering on an understanding, I have meditated for a long time, and have foreseen what might happen. It is not genius which reveals to me suddenly, secretly, what I have to say or to do in a circumstance unexpected by other people; it is reflection, it is meditation." - Napoleon I

                  K Offline
                  K Offline
                  Kevin Marois
                  wrote on last edited by
                  #8

                  OK, I don't get what's wrong here. Here's the CustomerName in my CustomerView

                  Here's the VM

                  private void Customer_PropertyChanged(object sender, PropertyChangedEventArgs e)
                  {
                  IsChanged = true;

                  ValidateCustomerName();
                  

                  }

                  private void ValidateCustomerName()
                  {
                  ClearErrors(nameof(Customer.CustomerName));

                  if (string.IsNullOrWhiteSpace(Customer.CustomerName))
                  {
                      AddError(nameof(Customer.CustomerName), "The Customer Name cannot be empty.");
                  }
                  

                  }

                  When I clear out the CustomerName field, the ValidateCustomerName method fires, and the error is added to the errors collection. I just don't see the error text on the UI. However, if instead of binding to Customer.CustomerName, if I put a string property on the VM called CustomerName and use that, then I see the error text.

                  In theory, theory and practice are the same. But in practice, they never are.” If it's not broken, fix it until it is. Everything makes sense in someone's mind.

                  1 Reply Last reply
                  0
                  Reply
                  • Reply as topic
                  Log in to reply
                  • Oldest to Newest
                  • Newest to Oldest
                  • Most Votes


                  • Login

                  • Don't have an account? Register

                  • Login or register to search.
                  • First post
                    Last post
                  0
                  • Categories
                  • Recent
                  • Tags
                  • Popular
                  • World
                  • Users
                  • Groups