Simple data binding does not work

I am new to WPF and I am trying to make a simple stopwatch application. It works fine if I do not perform data binding. Here is my xaml.

<Window x:Class="StopWatch.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:s="clr-namespace:StopWatch"
    Title="MainWindow" Height="318" Width="233">
<Window.Resources>
    <s:StopWatchViewModel x:Key="swViewModel" x:Name="swViewModel"></s:StopWatchViewModel>
</Window.Resources>
<Grid DataContext="{StaticResource swViewModel}"> 
    <Grid.RowDefinitions>
        <RowDefinition Height="Auto"/>
        <RowDefinition Height="auto"/>
        <RowDefinition Height="128*" />
    </Grid.RowDefinitions>
    <TextBlock Grid.Row="1" Height="49" HorizontalAlignment="Left" Margin="42,50,0,0" Name="txtTime" Text="{Binding Path=Message}" VerticalAlignment="Top" Width="147" FontSize="20" TextAlignment="Center" />
    <Button Content="Start" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="12,15,0,0" Name="startBtn" VerticalAlignment="Top" Width="58" Click="startBtn_Click" />
    <Button Content="Stop" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="76,15,0,0" Name="stopBtn" VerticalAlignment="Top" Width="58" Click="stopBtn_Click" />
    <Button Content="Reset" Grid.Row="2" Height="23" HorizontalAlignment="Left" Margin="140,15,0,0" Name="resetBtn" VerticalAlignment="Top" Width="59"/>
</Grid>

and here is the code in MainWindow

public partial class MainWindow : Window
{
    private StopWatchViewModel stopwatch;

    public MainWindow()
    {
        InitializeComponent();
        stopwatch = new StopWatchViewModel();
    }

    private void startBtn_Click(object sender, RoutedEventArgs e)
    {
        stopwatch.Start();
    }

    private void stopBtn_Click(object sender, RoutedEventArgs e)
    {
        stopwatch.Stop();
    }
}

and here is the code in StopWatchViewModel.cs

class StopWatchViewModel : INotifyPropertyChanged
{
    private DispatcherTimer timer;
    private Stopwatch stopwatch;
    private string message;

    public event PropertyChangedEventHandler PropertyChanged;

    public string Message
    {
        get
        {
            return message;
        }
        set
        {
            if (message != value)
            {
                message = value;
                OnPropertyChanged("Message");
            }
        }
    }

    public StopWatchViewModel()
    {
        timer = new DispatcherTimer();
        stopwatch = new Stopwatch();
        timer.Tick += new EventHandler(timer_Tick);
        timer.Start();
        stopwatch.Reset();
    }

    public void Start()
    {
        stopwatch.Start();
    }

    public void Stop()
    {
        stopwatch.Stop();
    }

    private void timer_Tick(object sender, EventArgs e)
    {
        Message = stopwatch.Elapsed.ToString(); // Doesn't work.
        // Message = "hello"; does not work too!
    }

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

}

I do not know where I was wrong.

EDIT . I got his job. So here is the working code for any link.

XAML, change the original to this

<Window x:Class="StopWatch.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:StopWatch"
Title="MainWindow" Height="318" Width="233">
<Grid> // partial code

and behind the code, change the constructor based on the Erno clause.

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

Thanks guys!

+3
source share
3 answers

Just replace the Message property this way and it will work:

 public string Message
 {
     get { return (string)GetValue(MessageProperty); }
     set { SetValue(MessageProperty, value); }
 }

 public static readonly DependencyProperty MessageProperty =
     DependencyProperty.Register("Message", typeof(string), 
     typeof(MainWindow), new UIPropertyMetadata(String.Empty));

EDIT . , ViewModel... .

ViewModel, . , (xaml)

EDIT: :

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

+3

, , WPF , . :

  • .
  • INotifyPropertyChanged, , .

, INotifyPropertyChanged, , :

  • PropertyChanged.
  • NotifyPropertyChanged, . ( ) : PropertyChanged(this, new PropertyChangedEventArgs(<nameofproperty>). , .
  • NotifyPropertyChanged ( ) , .
+4

, INotifyPropertyChanged. . , -, .

+1

Source: https://habr.com/ru/post/1787621/


All Articles