My property does not update using [CallerMemberName]
Asked Answered
B

1

0

Admittedly I am new to wpf. But i have spent some time Googling about it all and I am stumped.

in essence i want to update my TextBlock in my UI using Binding whenever my Model values change.

So this is my Model:

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

namespace WpfApplication1
{
    public class MyModel : INotifyPropertyChanged
    {
        protected void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }

        public event PropertyChangedEventHandler PropertyChanged;

        protected bool SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (Equals(storage, value))
            {
                return false;
            }

            storage = value;
            this.OnPropertyChanged(propertyName);
            return true;
        }

        public string MyField { get; set ; } 
    }
}

This is my UI:

 <Window x:Class="WpfApplication1.MainWindow"
        xmlns:viewModels="clr-namespace:WpfApplication1"
        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:local="clr-namespace:WpfApplication1"
        d:DataContext="{d:DesignInstance viewModels:MyModel, IsDesignTimeCreatable=True}"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <viewModels:MyModel></viewModels:MyModel>
    </Window.DataContext>
    <Grid>
        <StackPanel Orientation="Vertical">
            <TextBlock Text="{Binding  MyModel.MyField}"></TextBlock> 
          <Button Content="Click Me!" Click="Button_Click" />  
        </StackPanel>
    </Grid>
</Window>

This is my code behind:

using System.Windows;

namespace WpfApplication1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }
        public MyModel myModel = new MyModel();


        private void Button_Click(object sender, RoutedEventArgs e)
        {
            myModel.MyField = "has worked";
        }
    }
}

When i press the button the text does not change on the UI..?

Bergamot answered 7/1, 2016 at 12:54 Comment(0)
D
3

The instance you create in the code behind is not the same as you assign in xaml.

Change the button click event to

private void Button_Click(object sender, RoutedEventArgs e)
{
    var model = this.DataContext as MyModel;
    model.MyField = "has worked";
}

And the binding in xaml to

<TextBlock Text="{Binding MyField}"></TextBlock>

And in your viewmodel you are not calling the notify property changed. So create a private field and modify the property as below.

private string myField;

public string MyField
{
    get { return this.myField; }
    set { this.SetProperty(ref this.myField, value); }
}
Divulge answered 7/1, 2016 at 13:0 Comment(5)
thank you very much for such a clear and simple answer. I can accept in 3 minutes. Incidentally can the same be achieved using a static Class/Property?Bergamot
Static class can't implement interface INotifyPropertyChanged. Use singleton instance to bind "statically" with {x:Static MyClass.Instance.Property}.Divulge
ta for reply. i know what a singleton class is but unsure how to apply it in context to this?Bergamot
Also, you should not be using event handlers for buttons, read about how to bind Commands from viewmodel to the ui elements.Divulge
re: command thanks. i was going to look at that next :) why are event handlers not preferred then?Bergamot

© 2022 - 2024 — McMap. All rights reserved.