Search code examples
c#wpfdatetimexamlinotifypropertychanged

How To use xaml binding to realize clock notification?


I want to have a INotifyPropertyChanged Test. The following code works well. But I want to replace the cs-code-binding with xaml-binding. The question is how to do it while not affecting the program's function. Thanks for help!

XAML:

    <StackPanel Margin="5">
        <TextBox x:Name="textBox" Margin="5"/>
        <CheckBox x:Name="checkBox" Margin="5" HorizontalAlignment="Center"/>
        <Button x:Name="button" Margin="5" Content="UpdateTime" Click="button_Click"/>
    </StackPanel>

Code-Behind:

    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            BindingOperations.SetBinding(this.textBox, TextBox.TextProperty, new Binding("TimeNow") { Source = clock });
        }

        Clock clock = new Clock();
        private void button_Click(object sender, RoutedEventArgs e)
        {
            if ((bool)checkBox.IsChecked) clock.TimeNow = DateTime.Now;
        }
    }

    class Clock : INotifyPropertyChanged
    {
        private DateTime dateTime;
        public DateTime TimeNow
        {
            get { return dateTime; }
            set { dateTime = value; OnPropertyChanged(); }
        }

        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged([CallerMemberName] string propertyName = null)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
        }
    }

Solution

  • Set the DataContext property of the MainWindow to the Clock instance

    public MainWindow()
    {
        InitializeComponent();
        DataContext = clock;
    }
    

    and declare a Binding in XAML that uses the current DataContext as source object:

    <TextBox Text="{Binding TimeNow}"/>
    

    As an alternative to creating a Clock member in code, you could assign the DataContext in XAML

    <Window.DataContext>
        <local:Clock />
    </Window.DataContext>
    

    and access the Clock object in code behind like this:

    ((Clock)DataContext).TimeNow = DateTime.Now;