wwauth/Google.Solutions.WWAuth/View/ViewModelBase.cs (36 lines of code) (raw):

// // Copyright 2022 Google LLC // // Licensed to the Apache Software Foundation (ASF) under one // or more contributor license agreements. See the NOTICE file // distributed with this work for additional information // regarding copyright ownership. The ASF licenses this file // to you under the Apache License, Version 2.0 (the // "License"); you may not use this file except in compliance // with the License. You may obtain a copy of the License at // // http://www.apache.org/licenses/LICENSE-2.0 // // Unless required by applicable law or agreed to in writing, // software distributed under the License is distributed on an // "AS IS" BASIS, WITHOUT WARRANTIES OR CONDITIONS OF ANY // KIND, either express or implied. See the License for the // specific language governing permissions and limitations // under the License. // using System; using System.ComponentModel; using System.Diagnostics; using System.Linq.Expressions; using System.Reflection; using System.Runtime.CompilerServices; namespace Google.Solutions.WWAuth.View { /// <summary> /// Base class for view models. /// </summary> internal abstract class ViewModelBase : INotifyPropertyChanged { public event PropertyChangedEventHandler PropertyChanged; /// <summary> /// Notify observers about a property change. /// </summary> protected void RaisePropertyChange([CallerMemberName] string propertyName = null) { OnPropertyChanged(new PropertyChangedEventArgs(propertyName)); } protected virtual void OnPropertyChanged(PropertyChangedEventArgs args) { PropertyChanged?.Invoke(this, args); } /// <summary> /// Notify observers about a property change. Using this /// overload avoids having to use a (brittle) string to /// identify a property. /// /// Example: /// RaisePropertyChange((MyViewModel m) => m.MyProperty); /// </summary> protected void RaisePropertyChange<TModel, TProperty>( Expression<Func<TModel, TProperty>> modelProperty) { Debug.Assert(modelProperty.NodeType == ExpressionType.Lambda); if (modelProperty.Body is MemberExpression memberExpression && memberExpression.Member is PropertyInfo propertyInfo) { RaisePropertyChange(propertyInfo.Name); } else { throw new ArgumentException("Expression does not resolve to a property"); } } } }