0
votes

I've just started learning WPF desktop application. I've written some let say easy code below, to excercise binding operation.

The problem is: I wanted type sth in TextBox and see it simultaneously in TextBlock, but after compiling and running app, controls on form do not behave as I described.

Can anybody help me to fix it?

MainWindow.xaml:

<Window x:Class="Napisy.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:local="clr-namespace:Napisy"
        xmlns:mv="clr-namespace:Napisy.ModelWidoku"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <mv:NapisyModelWidoku x:Key="napisyModelWidoku"/>
    </Window.Resources>  

    <Grid DataContext="{StaticResource napisyModelWidoku}">
        <Grid.RowDefinitions>
            <RowDefinition Height="1*"/>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="2*"/>
            <RowDefinition Height="1*"/>
        </Grid.RowDefinitions>
        <TextBox Grid.Row="1" Margin="10,10,10,10" Text="{Binding Path=Tekst,Mode=TwoWay}"/>
        <TextBlock Grid.Row="2" Margin="10,10,10,10" Text="{Binding Path=Wyswietl,Mode=OneWay}"/>
    </Grid>
</Window>

ViewModel code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Napisy.Model;
using System.ComponentModel;

namespace Napisy.ModelWidoku
{
    public class NapisyModelWidoku : INotifyPropertyChanged
    {
        NapisyModel model = new NapisyModel();

        public string Tekst
        {
            get
            {
                return model.Tekst;
            }
            set
            {
                model.Tekst = value;
                OnPropertyChanged(nameof(Tekst));
                OnPropertyChanged(nameof(Wyswietl));
            }
        }
        public string Wyswietl
        {
            get
            {
                return model.Tekst;
            }
        }
        public event PropertyChangedEventHandler PropertyChanged;

        void OnPropertyChanged(string nazwa)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nazwa));
        }
    }
}

Model Code:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Napisy.Model
{
    public class NapisyModel
    {
        public string Tekst { get; set; }
    }
}

EDIT:

  • Problem description,
  • before class NapisyModelWidoku, acces modificator public added,
  • added OnPropertyChanged(nameof(Tekst));
  • instead OnPropertyChanged("Wyswietl"); used OnPropertyChanged(nameof(Wyswietl));

After typing text into TextBox still TextBlock not refresh automatically. Still hope I receive tips. Thanks

2
"do not behave as I intended" - is not really a good description of the problem. What doesn't work? I can see you forgot to rise notification for Tekst itself: OnPropertyChanged(nameof(Tekst)); - Sinatr
EDIT: "class NapisyModelWidoku" modified to "public class NapisyModelWidoku". Still not working. - lissajous

2 Answers

0
votes

Along with adding UpdateSourceTrigger in both bindings, make below change also,

 public string Tekst
    {
        get
        {
            return model.Tekst;
        }
        set
        {
            model.Tekst = value;
            OnPropertyChanged("Tekst");
            OnPropertyChanged("Wyswietl");
        }
    }
0
votes

I ran your code and it does not work because PropertyChanged is null. You have to set the datacontext of your view so that the PropertyChangedEventHandler can be binded.

Add in your code behind, i-e MainWindow.xaml.cs

public MainWindow()
{
     InitializeComponent();
     this.DataContext = new NapisyModelWidoku();
}