Bind Data From Property to Textblock - MVVM Light and WPF

Nov 10, 2013 at 9:59 AM
I have a textblock in WPF which is bound to a property in my ViewModel class. On click of a button I wish to modify the property and expect the same to be reflected in my textblock. I want all these to be done purely using MVVM (MVVMLight). I am using MMVM light and VS 2012. Challenges- On button click the changes are not being reflected. Though the program execution is going inside the property , changes are not being made.

Please Help !!

Program- ViewModel
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.Command;
using MvvmLight1_Trail.Model;
using System.ComponentModel;
using System.Threading;

namespace MvvmLight1_Trail.ViewModel
{

public class MainViewModel : ViewModelBase
{



    public RelayCommand PressCommand { get; private set; }
    Thread t;
    private string _welcomeTitle = string.Empty;


    public string MyText
    {
        get
        {
            return _welcomeTitle;
        }

        set
        {
            if (_welcomeTitle == value)
            {
                return;
            }

            _welcomeTitle = value;
            RaisePropertyChanged(MyText);
        }
    }

    /// <summary>
    /// Initializes a new instance of the MainViewModel class.
    /// </summary>
    public MainViewModel()
    {
        PressCommand = new RelayCommand(() => MyFunc());
        myfunc();
    }

    private void MyFunc()
    {
        this.MyText = "Hi2";
    }

    private void myfunc()
    {

        this.MyText = "Hello";
        this.MyText = "Hi";

    }
}
}
View:
<Window x:Class="MvvmLight1_Trail.MainWindow"
        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:ignore="http://www.ignore.com"
        mc:Ignorable="d ignore"
        Height="500"
        Width="500"
        Title="MVVM Light Application"
        DataContext="{Binding Main, Source={StaticResource Locator}}">
    
    

    <Grid x:Name="LayoutRoot">

        
        <TextBlock FontSize="34"
                   Text="{Binding Path=MyText,UpdateSourceTrigger=Default, Mode=TwoWay}"
                   VerticalAlignment="Center"
                   HorizontalAlignment="Center"
                   TextWrapping="Wrap" />
        <Button Width="100" Height="100" Command="{Binding PressCommand}" Margin="198.985,277.537,193.014,92.462" Content="Press Me"/>
       
    </Grid>
</Window>
Nov 10, 2013 at 1:19 PM
Edited Nov 10, 2013 at 4:14 PM
What exactly do you see when you run the program?

From inspection, I expect the TextBlock to display:
"Hello" // This will not be visible, as it is immediately overwritten by 'Hi' in the call to myfunc()
"Hi"
// Click the button
"Hi2" // in MyFunc()

I toggled up a demo app from the Galasoft "MVVMLight (WPF4)" template, and it works as expected.
You can get my project from Skydrive: http://sdrv.ms/19RD1ge
Nov 12, 2013 at 3:34 PM
Edited Nov 12, 2013 at 4:25 PM
The problem lies in your property:
public string MyText
    {
        get
        {
            return _welcomeTitle;
        }

        set
        {
            if (_welcomeTitle == value)
            {
                return;
            }

            _welcomeTitle = value;
            RaisePropertyChanged(MyText);
        }
    }
What exactly is RaisePropertyChanged(MyText); doing here? You aren't sending a notification that the property called "MyText" needs updating, rather you are saying a property that is named with what ever the current value of the text property MyText, (which is first "Hello", and then "Hi"), should be updated.

You should follow the mvvmlight code snippets when creating INotifiyPropertyChanged properties, which contain a const string with the property name like so:
public const string MyTextPropertyName = "MyText";
and then your call to RaisePropertyChanged looks like this:
            RaisePropertyChanged(MyTextPropertyName );
Coordinator
Nov 12, 2013 at 4:36 PM
I do that mistake too sometimes. My guess is that you wanted to do
RaisePropertyChanged(() => MyText);
Cheers
Laurent
Nov 13, 2013 at 9:57 AM
This works fine for me
private string _serviceURL;
        public string ServiceURL
        {
            get { return this._serviceURL; }
            set
            {
                if (this._serviceURL != value)
                {
                    this._serviceURL = value;
                    RaisePropertyChanged("ServiceURL");
                }
            }
        }