Octan
Octan

Reputation: 348

WPF - Instance subclass from superclass

I'm doing and WPF application and I have a ViewModel that I use in several Views and in DataGrids.

Now I have another View that requires an extended or decorated version of that ViewModel. So I decided to go for inheritance in this way:

public class StandardViewModel
{
    public string FirstName { get; set; }
    public string LastName { get; set; }
}

public class ExtendedViewModel : StandardViewModel
{
    public string Email { get; set; }
}

However, I want to decorate and existing instance of the StandardViewModel. Specifically the selected object in the DataGrid so it can be passed into the other View.

The new View needs access to the properties of both classes (the Email and the FirtsName and LastName)

So I'm thinking of ways to creating a constructor for my ExtendedViewModel.

My idea is to copy the base instance directly.

public class ExtendedViewModel : StandardViewModel
{
    public string Email { get; set; }

    public ExtendedViewModel(StandardViewModel base)
    {
        this = base
    }
}

Edit

I'm doing this for not only one but several classes. And they do not have only two properties so I'm trying to avoid copying the values one by one.

Upvotes: 0

Views: 137

Answers (2)

Octan
Octan

Reputation: 348

Finally I'll avoid using inheritance and I'll create a new class, expose the base class and subscribe to INotifyPropertyChanged as described here and here.

This way I'll be able to have properties that depend on the Base ViewModel updated as done with FullName below.

The resulting ViewModel will look like:

public class ExtendedViewModel
{
    public StandardViewModel Base { get; set; }
    public string Email { get; set; }

    public string FullName {
        get => Base.FirstName + Base.LastName;
    }

    public ExtendedViewModel(StandardViewModel base)
    {
        Base = base
        Base.PropertyChanged += BaseChanged
    }

    private void BaseChanged(object sender, PropertyChangedEventArgs e)
    {
        // Here check if FirstName or LastName changed and
        RaisePropertyChanged("FullName");
    }
}

In the view I will bind directly to Email or to Base.FirstName.

Upvotes: 2

lidqy
lidqy

Reputation: 2453

In oversimplified terms a decorator owns an instance of the class it decorates and delegates functionality existing in the owned class to that class, while adding new functionality uncoupled from the owned class instance.

public class StandardViewModel
{
    public virtual string FirstName { get; set; }
    public virtual string LastName { get; set; }
}

public class ExtendedViewModel : StandardViewModel
{
    private StandardViewModel _standard;
    public ExtendedViewModel (StandardViewModel standard)
    {
         if (standard.GetType() != typeof(StandardViewModel )) {
            throw new ArgumentException ("Expected a non derived standard view model", nameof(standard));
         }
        _standard = standard;
    }
    public string Email { get; set; }
    public override string FirstName { 
        get => _standard.Firstname; 
        set  => _standard.Firstname = value; 
    }
    public override string LastName { 
        get => _standard.LastName; 
        set  => _standard.LastName = value; 
    }

}

Upvotes: 1

Related Questions