Hello StackOverflow,
I've coded a Prop<T>
class to simplify implementation of the INotifyPropertyChanged
interface and handle setting of its default value. Correct use of the class is as follows:
C#: public Prop<string> PropProperty { get; } = new("Default Text");
XAML: <TextBox Text="{Binding PropProperty.Value, UpdateSourceTrigger=PropertyChanged}" />
My goal is to display an in-editor XAML warning if a user binds to PropProperty
instead of to PropProperty.Value
. Currently, it is not obvious if the user incorrectly binds to the class itself; its internal OnPropertyChanged
method is simply never invoked. Is there a way to display an in-editor warning when user binds to the Prop<T>
class instructing them to instead bind to its Value
property to help reduce user error?
Below is the full code of the Prop
class, followed by an example usage:
// Prop.cs
using System;
using System.ComponentModel;
using System.Collections.Generic;
using System.Runtime.CompilerServices;
namespace Darkwell.MVVM;
public sealed class Prop<T> : INotifyPropertyChanged {
#region VARIABLES
public T Value {
get => _value;
set => SetField(ref _value, value);
}
private T _value;
#endregion
#region METHODS
public Prop() {
if (_value != null) {
return;
}
if (typeof(T) == typeof(string)) {
_value = (T)(object)string.Empty;
return;
}
_value = Activator.CreateInstance<T>();
}
public Prop(T @default) =>
_value = @default;
public event PropertyChangedEventHandler? PropertyChanged;
#endregion
#region METHODS
private void OnPropertyChanged([CallerMemberName] string? propertyName = null) =>
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
private bool SetField<TU>(ref TU field, TU value, [CallerMemberName] string? propertyName = null) {
if (EqualityComparer<TU>.Default.Equals(field, value)) {
return false;
}
field = value;
OnPropertyChanged(propertyName);
return true;
}
#endregion
}
// PropExampleView.xaml.cs
using System.Windows;
using Darkwell.MVVM;
public partial class PropExampleView : Window {
public Prop<string> PropProperty { get; } = new("Default Text");
public PropExampleView() {
InitializeComponent();
}
}
<!-- PropExampleWindow.xaml -->
<Window x:Class="PropExampleView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:global="clr-namespace:"
mc:Ignorable="d"
d:DataContext="{d:DesignInstance global:PropExampleView}"
Title="PropExample" Height="450" Width="800">
<StackPanel>
<TextBox Text="{Binding PropProperty.Value}" />
</StackPanel>
</Window>
I would prefer an approach that would work in any IDE, but am open to approaches specific to JetBrains Rider.
I've searched on StackOverflow and the web at large with no result. I've also explored available properties (including Rider-specific ones) and NuGet packages (my least-preferred approach), but also returned empty-handed.
Any assistance is greatly appreciated!
Thank you in advance and be well!