0

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!

  • Please provide enough code so others can better understand or reproduce the problem. – Community Aug 26 '22 at 16:51
  • Are you looking for something like this JetBrains ReSharper plugin: https://plugins.jetbrains.com/plugin/11743-reactiveproperty-xaml-binding-corrector? If that's what you're looking for, although the plugin is set to be compatible with ReSharper, it should work with Rider as well as they share the same code analysis engine. You also may need to contact the author or make a PR to update the plugin to match your Rider version. – Jura Gorohovsky Aug 27 '22 at 07:58
  • I dunno about resolving your issue as stated. Maybe it'd help to understand your intended purpose. Why would one need such a thing? – Andy Aug 27 '22 at 09:34
  • Have you considered using designerdata? It'd fail in the designer if there's no value to bind. – Andy Aug 27 '22 at 09:35
  • Per @Community's recommendation, I'd added additional code. – S. Darkwell Aug 27 '22 at 17:28
  • @JuraGorohovsky, I'm don't have access to check it out at the moment, but from what I can tell, that's exactly what I'm seeking, except for my own ```Prop``` class. I'll have to see look into how they do it, or perhaps use their solution entirely. Thank you so much! – S. Darkwell Aug 27 '22 at 17:28
  • @Andy, my hope is to reduce user (eg: my) error, binding to ```PropProperty``` instead of ```PropProperty.Value``` in the given example by providing an in-editor warning when such a binding is detected. As for designerdata, I'm not completely fluent in XAML, but I'm not sure this would address it, as both ```PropProperty``` and ```PropProperty.Value``` do exist. – S. Darkwell Aug 27 '22 at 17:28
  • Designer data shows you the result in your designer. If something doesn't bind to anything then you won't see whatever your expected result is. To put it another way. If everything works fine and you get your expected result then your bindings are working. – Andy Aug 28 '22 at 09:25

0 Answers0