如何使用xaml绑定实现时钟通知?

How To use xaml binding to realize clock notification?

我想要一个 INotifyPropertyChanged 测试。以下代码运行良好。但我想用 xaml-binding 替换 cs-code-binding。 问题是如何在不影响程序功能的情况下做到这一点。 感谢您的帮助!

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>

代码隐藏:

    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));
        }
    }

将 MainWindow 的 DataContext 属性 设置为 Clock 实例

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

并在 XAML 中声明一个使用当前 DataContext 作为源对象的绑定:

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

作为在代码中创建 Clock 成员的替代方法,您可以在 XAML

中分配 DataContext
<Window.DataContext>
    <local:Clock />
</Window.DataContext>

并像这样在后面的代码中访问 Clock 对象:

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

使用 nuget 包 ReactiveUI.FodyReactiveUI.WPF 你可以写一个 ViewModel

public class MainViewModel : ReactiveObject
{
    public MainViewModel()
    {
        var canUpdateTime = this.WhenAnyValue(e => e.MayUpdateTime);
        UpdateTimeCommand = ReactiveCommand.Create(() => TimeNow = DateTime.Now, canUpdateTime);
    }

    [Reactive] public bool MayUpdateTime { get; set; }
    [Reactive] public DateTime TimeNow { get; set; }
    public ReactiveCommand<Unit, DateTime> UpdateTimeCommand { get; }
}

和视图

<Window
  x:Class="ReactiveWpfApp5.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:local="clr-namespace:ReactiveWpfApp5"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  xmlns:viewModels="clr-namespace:ReactiveWpfApp5.ViewModels"
  Title="MainWindow"
  Width="800"
  Height="450"
  mc:Ignorable="d">
  <Window.DataContext>
    <viewModels:MainViewModel />
  </Window.DataContext>
  <DockPanel>
    <StackPanel>
      <TextBox Text="{Binding TimeNow, Mode=TwoWay}" />
      <CheckBox Content="May Update Time" IsChecked="{Binding MayUpdateTime}" />
      <Button Command="{Binding UpdateTimeCommand}" Content="Update Time" />
    </StackPanel>
  </DockPanel>
</Window>

就这些了