0

Alright, so I'm new to MVVM and trying to do some data-binding and can't get it working.
I built a WPF application with two user-controls UC1 and UC2 and a View-Model Class VM1.
UC1 consists of a button whose command is specified in VM1 and UC2 consists of three text boxes whose texts are bound to properties in VM1. So what I want is, when I click on the button the text of each textbox must change. But when I click the button nothing happens. See below for the code.

ViewModel Class - VM1:

namespace TestApp.ViewModels
{
public class  VM1 : INotifyPropertyChanged
{
    #region Definations

    private double heading;
    private double attitude;
    private double bank;

    public double Heading
    {
        get { return heading; }
        set
        {
            heading = value;
            RaisePropertyChanged("Heading");
        }
    }

    public double Attitude
    {
        get { return attitude; }
        set
        {
            attitude = value;
            RaisePropertyChanged("Attitude");
        }
    }

    public double Bank
    {
        get { return bank; }
        set
        {
            bank = value;
            RaisePropertyChanged("Bank");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    private void RaisePropertyChanged(string property)
    {
        if (PropertyChanged != null)
        {
            PropertyChanged(this, new PropertyChangedEventArgs(property));
        }
    }

    #endregion

    //public TrayModel TrayModel { get; set; }
    public ICommand UpdateViewAxesToFrontCommand { get; set; }


    public  VM1()
    {
        UpdateViewAxesToFrontCommand = new RelayCommand(UpdateViewAxesToFront, canExecuteMethod);
    }

    public bool canExecuteMethod(object parameter)
    {
        return true;
    }

    public void UpdateViewAxesToFront(object param)
    {
        Attitude = 10;
        Heading = 0;
        Bank = 0;
    }

}
}

UC1:

<UserControl x:Class="TestApp.UserControls.UC1"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
         xmlns:hc="https://handyorg.github.io/handycontrol"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:VM="clr-namespace:TestApp.ViewModels"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:TestApp.UserControls"
         mc:Ignorable="d">
<UserControl.DataContext>
    <VM: VM1/>
</UserControl.DataContext>
<hc:ButtonGroup>
    <Button Style="{StaticResource ButtonIcon}" Command="{Binding Path=UpdateViewAxesToFrontCommand, UpdateSourceTrigger=PropertyChanged}" hc:IconElement.Geometry="{StaticResource CubeFontFaceGeometry}"/>
</hc:ButtonGroup>
</UserControl>

UC2:

<UserControl x:Class="TestApp.UserControls.UC2"
         xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:hc="https://handyorg.github.io/handycontrol"
         xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
         xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
         xmlns:VM="clr-namespace:TestApp.ViewModels"
         xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
         xmlns:local="clr-namespace:TestApp.UserControls"
         mc:Ignorable="d">
<UserControl.DataContext>
    <VM: VM1/>
</UserControl.DataContext>
<StackPanel>
    <TextBox Text="{Binding Attitude, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBox Text="{Binding Bank, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    <TextBox Text="{Binding Heading, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</UserControl>

I've also set DataContext in code-behind of each user-control as follows.

InitilizeComponent();    
DataContext = new ViewModels.VM1();  

Upon loading, the values in each text boxes are set to 0, and once I click the button the values remain 0 and don't change to 10, 0, 0 as expected.

  • You must not explicitly set the DataContext of the UserControls. Doing so prevents that they inherit the DataContext value from their parent element so that they can operate on the same view model instance. Remove the DataContext assignments from their XAML and code behind, and assign a single view model instance to the DataContext of the Window (or the common parent element of the controls). – Clemens Aug 06 '21 at 13:23
  • @Clemens Ok, where should I assign a single view model instance to the DataContext of the Window? In the Window's xaml or code-behind? Does it make any difference where I assign it? – Dodger 9886 Aug 06 '21 at 13:28
  • Is your command triggering ? – N.J Aug 06 '21 at 13:29
  • @N.J Yes the command is triggering. Checked it by writing to the console in the `UpdateViewAxesToFront` method. – Dodger 9886 Aug 06 '21 at 13:29
  • @Dodger9886 remove Datacontext from the usercontrol and from code behid and Set the DataConext in the parent window . Above comment Clemens already suggested that – N.J Aug 06 '21 at 13:51
  • @Dodger9886 It doesn't matter where you assign it. – Clemens Aug 06 '21 at 14:03

0 Answers0