如何使用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.Fody
和 ReactiveUI.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>
就这些了
我想要一个 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.Fody
和 ReactiveUI.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>
就这些了