0
votes

I have the following in my Entity Framework class:

public int NumberOfIndividualEngagements { get; set; } 
public int NumberOfGroupEngagements { get; set; } 

[NotMapped]
public int TotalAudienceReached => NumberOfIndividualEngagements + NumberOfGroupEngagements != 0 ? NumberOfIndividualEngagements + NumberOfGroupEngagements : 0;

In the View I have a TextBlock referencing TotalAudienceReached as the text. I also have TextBoxes for the two items in the equation. It seems that when I update the either of the two variables (NumberOfIndividualEngagements, NumberOfGroupEngagements), the TotalAudienceReached does not update and the View is not updated.

Question, is this even possible to accomplish in this manner or do I need to setup some stand alone properties in my ViewModel that references these changes?

EDIT

My VM is as such:

namespace Core
{
    public class MyViewModel : BaseViewModel
    {
        #region Public Properties

        /// <summary>
        /// The Parent object
        /// </summary>
        public Parent Parent 
        {
            get => _Parent;
            set 
            {
                Parent = _Parent;
                OnPropertyChanged(nameof(Parent));
            }
        }

        private Parent _Parent;

        // Other properties...

        public MyViewModel()
        {
            // Load it...
        }
    }
}

Here is my EF dataset

namespace Data
{
    [Table("Parent")]
    public class Parent : BaseData
    {
        public int ParentId { get; set; }
        public int NumberOfIndividualEngagements { get; set; }             
        public int NumberOfGroupEngagements { get; set; } 
        // Other various properties (int, string, bool, etc.)

        [NotMapped]
        public int TotalAudienceReached => NumberOfIndividualEngagements + NumberOfGroupEngagements != 0 ? NumberOfIndividualEngagements + NumberOfGroupEngagements : 0;
    }
}

The DataContext of the View is set to the MyViewModel.

The DataContext of the Container (i.e. Grid, Stackpanel) is set to the Parent property in MyViewModel.

The Controls in the container are bound to the property of the Parent class.

2
The magic happens when you add INotifyPropertyChanged in your ViewModel, do some research on this, there is a lot in the SO - Celso Lívero
@CelsoLívero When I add that to the class, then nothing updates in the View. I also have TextBlocks with the two items. I have an "Overview" panel that gives a quick look at everything. These no longer update when I add INotifyPropertyChanged. - Red_Phoenix
See my answer again, I edited it - Celso Lívero
The ViewModel is a specialized model for the view. You don't need to use your models (EF), just create a VM with properties you want and update your model. - Luis
@Luis yeah that is what I did. I answered my own question. Thank you though. - Red_Phoenix

2 Answers

0
votes

Your ViewModel should look something like this

public class MyViewModel : INotifyPropertyChanged
{
    public int NumberOfIndividualEngagements 
    {
        get => _numberOfIndividualEngagements;
        set
        {
            _numberOfIndividualEngagements = value;
            OnPropertyChanged(nameof(NumberOfIndividualEngagements));
            OnPropertyChanged(nameof(TotalAudienceReached));
        }
    }
    public int NumberOfGroupEngagements 
    {
        get => _numberOfGroupEngagements;
        set
        {
            _numberOfGroupEngagements = value;
            OnPropertyChanged(nameof(NumberOfGroupEngagements));
            OnPropertyChanged(nameof(TotalAudienceReached));
        }
    }

    public int TotalAudienceReached => 
        NumberOfIndividualEngagements + NumberOfGroupEngagements != 0 
                ? NumberOfIndividualEngagements + NumberOfGroupEngagements 
                : 0;

}

Edit: I'd never reused a model property this way in my viewmodel, so i'm not certain abaout this, but, if you edit a child of your Parent, it may not update your View, so whenever your children update the parents, you must set the Parent property again, like this:

Parent = new Parent 
{
    ParentId = <your new value>,
    NumberOfIndividualEngagements = <your new value>,
    NumberOfGroupEngagements = <your new value>
}

in this way, it will trigger the OnPropertyChanged updating you View.

0
votes

Found a different way. The NotMapped properties are there for reporting purposes. I really didn't need to use them. Therefore I decided to make a property in the ViewModel and have the Getter/Setter reference the Parent object properties. This way the controls will be updated from the VM properties and then set the properties in the parent.

namespace Core
{
    public class MyViewModel : BaseViewModel
    {
        #region Public Properties

        /// <summary>
        /// The Parent object
        /// </summary>
        public Parent Parent { get; set; }

        public int NumberOfIndividualEngagements
        {
            get => Parent.NumberOfIndividualEngagements;
            set
            {
                Parent.NumberOfIndividualEngagements = value;
                OnPropertyChanged(nameof(NumberOfIndividualEngagements));
                OnPropertyChanged(nameof(TotalAudienceReached));
            }
        }

        public int NumberOfGroupEngagements
        {
            get => Parent.NumberOfGroupEngagements;
            set
            {
                Parent.NumberOfGroupEngagements = value;
                OnPropertyChanged(nameof(NumberOfGroupEngagements));
                OnPropertyChanged(nameof(TotalAudienceReached));
            }
        }

        // Other properties...

        public MyViewModel()
        {
            // Load it...
        }
    }
}