c# – WPF After ICommand INotifyPropertyChanged is called, but not updating UI [MVVM]

When the View is initialized, their standard value “VM”, definied in the ViewModelis updated trough the Model and updated in the View. However, when the ICommand NavigationCommand is triggered, the code in the OnNavigationCommand method executes, and even the OnPropertyChanged (INotifyPropertyChanged) method is called in the Model. However, the textboxes in the UI still remain the same value: “VM”. I have tried a lot, but can’t seem to find the problem. Hope you can help.

View

<vw:View xmlns:cc="clr-namespace:HMI.CustomControl" xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
    x:Class="HMI.ZoneFView"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vw="http://inosoft.com/visiwin7"
    xmlns:main="clr-namespace:HMI.Views.MainRegion"
    xmlns:local="clr-namespace:HMI" xmlns:dialogregion="clr-namespace:HMI.Views.DialogRegion" 
         mc:Ignorable="d"
         DataContext="{vw:AdapterBinding ViewModel}">
    
    <Viewbox>
        <Grid x:Name="LayoutRoot" Width="140" Height="220.5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="3"/>
                <ColumnDefinition Width="5*"/>
                <ColumnDefinition Width="3"/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition Height="5" />
                <RowDefinition Height="5*" />
                <RowDefinition Height="5" />
            </Grid.RowDefinitions>

            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding theModel.VisibilityFFUView}" Margin="57,16,7,62" />
            <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding theModel.VisibilityFFUView}" Margin="57,48,7,30" />

        </Grid>
    </Viewbox>

</vw:View>

View.cs

using HMI.Views.MainRegion;
using VisiWin.ApplicationFramework;

namespace HMI
{
    [ExportView("ZoneFView")]
    public partial class ZoneFView : VisiWin.Controls.View
    {
        
        public ZoneFView()
        {
            this.InitializeComponent();
        }
    }
}

ViewModel

using System;
using System.ComponentModel.Composition;
using System.Windows.Input;
using VisiWin.ApplicationFramework;
using VisiWin.Commands;

namespace HMI.Views.MainRegion
{
    [ExportAdapter("ViewModel")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    class ViewModel : AdapterBase
    {
        #region Constructor

        public Model Model { get; set; }

        public ViewModel()
        {

            // If the VisiWin system is not in the runtime, the VW7 functionalities cannot be accessed
            if (ApplicationService.IsInDesignMode)
            {
                return;
            }

            // Create the Action Commands
            this.NavigationCommand = new ActionCommand(OnNavigationCommand);

            Model = new Model()
            {
                VisibilityFFUView = "VM"
            };
        }

        #endregion

        #region CordisAdapterBase implementation

        // Called when the view on which this adapter is located as DataContext is loaded
        public override void OnViewAttached(IView view)
        {
            base.OnViewAttached(view);
        }

        public override void OnViewDetached(IView view)
        {
            base.OnViewDetached(view);
        }

        #endregion

        #region NavigationCommand - Command from the view into the ViewModel

        public ICommand NavigationCommand { get; set; }

        // NavigationCommand event call
        // Will be called if one of the buttons in the "AppbarView" view is clicked.
        // The command of the model is linked to the button via the Command property.
        private void OnNavigationCommand(object commandParameter)
        {
            if (commandParameter != null)
            {
                if (ApplicationService.IsInDesignMode) return;

               string strParameter = commandParameter.ToString();

                switch (strParameter)
                {
                    case "FFU":
                        Model.VisibilityFFUView = "Turn on";
                        break;
                    case "FFUswitch":
                        Model.VisibilityFFUView = "Turn off";
                        break;
                    default:
                        break;
                }
            }
            else
            {
                throw new ArgumentNullException(nameof(commandParameter));
            }
        }

        #endregion
        
    }
}

Model

using System.ComponentModel.Composition;
using VisiWin.ApplicationFramework;

namespace HMI.Views.MainRegion
{
    [ExportAdapter("Model")]
    [PartCreationPolicy(CreationPolicy.NonShared)]
    public class Model : ObserverableObject
    {
        private string _visibilityFFUView;

        public string VisibilityFFUView
        {
            get { return _visibilityFFUView; }
            set
            {
                _visibilityFFUView = value;
                OnPropertyChanged();
            }
        }
    }
}

ObservableObject

using System.ComponentModel;
using System.Runtime.CompilerServices;

namespace HMI.Views.MainRegion
{
    public class ObserverableObject : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }
}

UPDATE
I have added the NavigationView, and shifted both the DataContext of NavigationView and ZoneFView to XAML to reduce some code..

NavigationView

<vw:View xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity" 
         x:Class="HMI.Views.Common.AppbarView" 
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:vw="http://inosoft.com/visiwin7" xmlns:local="clr-namespace:HMI" 
         mc:Ignorable="d" d:DesignWidth="200" d:DesignHeight="638"
         DataContext="{vw:AdapterBinding ViewModel}">
    <Grid x:Name="LayoutRoot" Background="{DynamicResource AppbarBackgroundBrush}">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*" />
            <ColumnDefinition Width="8" />

        </Grid.ColumnDefinitions>
        <Rectangle Grid.Column="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Fill="{DynamicResource AccentBrush}" StrokeThickness="0" />
        <StackPanel Grid.Column="0" Margin="10,10,0,0" VerticalAlignment="Top">
            <vw:NavigationRadioButton HorizontalAlignment="Stretch" RegionName="MainRegion" ViewName="HomeView" IsChecked="True" Style="{DynamicResource AppbarNavigationRadioButtonStyle}" VerticalAlignment="Top" Height="52" Symbol="{DynamicResource appbar.tiles.nine}" LocalizableText="@Appbar.Dashboard" Margin="0,0,0,0" SymbolHorizontalAlignment="Left" />
            <vw:NavigationRadioButton HorizontalAlignment="Stretch" RegionName="MainRegion" ViewName="FFUnitsView" IsChecked="false" Style="{DynamicResource AppbarNavigationRadioButtonStyle}" VerticalAlignment="Top" Height="52" Symbol="{DynamicResource appbar.interface.button}" LocalizableText="@Appbar.FFUnits" Margin="0,10,0,0" BorderThickness="1,1,0,1" CommandParameter="FFU" Command="{Binding NavigationCommand}">
            </vw:NavigationRadioButton>
        </StackPanel>
    </Grid>

</vw:View>

Solution:

Like Clemens said I did use two instances of my DataContext. Therefore, when I did updated my property

I found this post on how to solve this problem: How can I create only one instance of a DataContext for multiple windows? Thanks for the input! Case closed.

Leave a Comment