Search code examples
c#validationpropertiesuser-input

How to "return" an error message from a C# property setter to the user?


I have a windows form that allows the user to input an integer value. This value is used to update a member of a separate class (foo) so long as it falls within a certain valid range. If the user inputs something invalid, I want an error message to tell the user that the default value for the parameter will be used.

In order to accomplish this, I have been error checking the user input within the code for the windows form before letting foo set the field in question, and simply displaying a message if the input fails the check.

But what I would like to do is send the raw user input to a property setter within the class foo and have the property setter handle all the error checking. For other functions in foo that may require a message be displayed on the user interface, I am simply returning a string, but to my knowledge there is no way to return any sort of status or value from a property setter. Is there a graceful way to bubble up a status message of some sort from a property setter to a different function? I don't want foo to modify the user interface directly.

Thanks in advance for any help or tips, and I apologize if my question is too vague or should be asked differently as I am new to StackOverflow


Solution

  • I fixed my problem (as well as removed the need to return strings from nearly all my functions) by implementing INotifyPropertyChanged in my class foo and raising a PropertyChanged event to be caught by the windows form whenever it was necessary to let the user know something had changed.

    in class foo-

    public class foo : INotifyPropertyChanged {
    
        public event PropertyChangedEventHandler PropertyChanged;
        public int bar;
    
        private void NotifyPropertyChanged(string type) {
            if (PropertyChanged != null) {
                PropertyChanged(this, new PropertyChangedEventArgs(type));
            }
        }
    
        private void test(){
            bar = 1;
            NotifyPropertyChanged("changed int");
        }
    
    }
    

    in the windows form:

    public partial class GUI : Form {
         foo fooinstance = new foo();
    
         public GUI(){
               InitializeComponent();
               fooinstance.PropertyChanged += doEvent;
         }
    
         private void doEvent(object sender, PropertyChangedEventArgs e){
            foo updated = sender as foo;
            if (object.ReferenceEquals(e.PropertyName, "changed int")) {
                ShowWhatChanged(updated.bar); //show on GUI
            }
         }
    

    }

    EDIT: A more graceful and cleaner way that I ended up using was to utilize callbacks. The GUI passed a function pointer into foo upon instantiation and foo used it as a delegate to pass strings back to the GUI whenever necessary. No events required:

    public class foo {
    
        public delegate void UpdateCallback(string msg);
        private UpdateCallback _ucb;
        public foo(UpdateCallback cb){
            _ucb = cb;
        }
    
        private void test(){
            if(_ucb != null) {
               _ucb("Message Here");
            }
        }
    }
    
    public partial class GUI : Form {
    
         public GUI(){
               InitializeComponent();
               foo fooinstance = new foo(showmessage);
    
         }
    
         private void showmessage(string msg){
               //do whatever with the message
         }
    }