WPF 绑定 - 标签绑定问题
WPF Binding - Lable binding problems
我正在尝试使用 Async DataBinding
,这是因为我需要在我的应用程序上执行多个必须访问 UI 控件的线程。为此,我将 Label
声明为:
<Label x:Name="SyncRange" Content="{Binding NextSynchronization, IsAsync=True}" />
(注意是我自己的控件),所以在控件的class里面我定义了这个:
private string nextSync = "N/A";
public string NextSynchronization {
get {
return nextSync;
}
set {
nextSync = value;
}
}
如何看到 nextSync
的默认值是 N/A
,我可以从任何 classes 更改变量的值。
此时我已经以这种方式在我的主窗口中导入了控件:
xmlns:OwnControl="clr-namespace:SynchronizationTool"
并将其用作:
<OwnControl:Scheduler x:Name="Scheduler"/>
在主窗口中 class 当我按下保存按钮时我想在标签中显示一个新值,所以:
private void Save_Click(object sender, RoutedEventArgs e)
{
Scheduler.NextSynchronization = "test";
}
标签应该自动绑定值test
,但不幸的是,标签仍然是空的。我做错了什么?
更新
我在我的控制范围内创建了一个 Test
class:
public class Test {
private string nextSync = "N/A";
public string NextSynchronization {
get {
return nextSync;
}
set {
nextSync = value;
}
}
}
并且在 MainWindow
我使用这个:
DataContext = new CScheduler.Test();
似乎已使用 N/A
正确初始化标签
这只是评论。首先你应该在这一行放置一个断点:
return nextSync;
但我主要想知道的是,为什么您在 "set" 之后没有任何 OnPropertyChanged(您的 class 实现了 INotifyPropertyChanged?):
public string NextSynchronization
{
get
{
return nextSync;
}
set
{
nextSync = value;
OnPropertyChanged("NextSynchronization");
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
下面是正确设置 DataContext 的示例:
<Window x:Class="TestApplication.TestWindow"
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"
mc:Ignorable="d"
Title="TestWindow" Height="300" Width="300">
<Grid>
<TextBox Text="{Binding Text}"></TextBox>
<CheckBox IsChecked="{Binding IsChecked}"></CheckBox>
<Button Content="{Binding BtnText}"></Button>
</Grid>
public partial class MainWindow : Window
{
//MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
//Create a new Instance of your ViewModel
MyViewModelClass viewModel = new MyViewModelClass();
//Set the DataContext (BindingContext (i.e. where to look for the Bindings) to your ViewModel
DataContext = viewModel;
}
}
正在定义您的 ViewModelClass:
public class MyViewModelClass: INotifyPropertyChanged
{
//Add Constructor
public MyViewModelClass()
{
}
private string _text = "sampleText shown in the TextBox";
public string Text
{
get { return _text; }
set
{
nextSync = value;
OnPropertyChanged();//PropertyName will be passed automatically
}
}
private string _isChecked = true;//CheckBox is checked by default
public string IsChecked
{
get { return _isChecked ; }
set
{
nextSync = value;
OnPropertyChanged();//PropertyName will be passed automatically
}
}
private string _btnText = "Click Me";//Text to display on the button
public string BtnText
{
get { return _btnText ; }
set
{
nextSync = value;
OnPropertyChanged();//PropertyName will be passed automatically
}
}
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
//When using the [CallerMemberName] Attribute you dont need to pass the PropertyName to the method which is pretty nice :D
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Implementation of INotifyPropertyChanged
}
基本上 DataContext
告诉 UI 在哪里寻找绑定。
如果未设置,则在构建时 VisualStuido 中的输出 window 中会显示绑定错误。
更新:
如果使用 UserControls
:
在您放置 xaml 的项目中添加一个名为 UserControls 的文件夹。
在您的 Window:
中为它们添加命名空间
xmlns:userControls="clr-namespace:<YourApplicationName>.UserControls"
然后将 UserControl
添加到 MainWindow 的网格中:
<userControls:MyUserControl1></userControls:MyUserControl1>
重点来了:
- 如果您不在 UserControl.xaml.cs 中为 UserControl 设置 DataContext
它将自动使用来自父控件的控件(在您的情况下是 Window)
- 因此,您在 window 或用户控件中获得的所有绑定都放入那个 1 ViewModel
- 只为Window设置
DataContext
。
- 现在应该从该视图模型中获取所有绑定。
我正在尝试使用 Async DataBinding
,这是因为我需要在我的应用程序上执行多个必须访问 UI 控件的线程。为此,我将 Label
声明为:
<Label x:Name="SyncRange" Content="{Binding NextSynchronization, IsAsync=True}" />
(注意是我自己的控件),所以在控件的class里面我定义了这个:
private string nextSync = "N/A";
public string NextSynchronization {
get {
return nextSync;
}
set {
nextSync = value;
}
}
如何看到 nextSync
的默认值是 N/A
,我可以从任何 classes 更改变量的值。
此时我已经以这种方式在我的主窗口中导入了控件:
xmlns:OwnControl="clr-namespace:SynchronizationTool"
并将其用作:
<OwnControl:Scheduler x:Name="Scheduler"/>
在主窗口中 class 当我按下保存按钮时我想在标签中显示一个新值,所以:
private void Save_Click(object sender, RoutedEventArgs e)
{
Scheduler.NextSynchronization = "test";
}
标签应该自动绑定值test
,但不幸的是,标签仍然是空的。我做错了什么?
更新
我在我的控制范围内创建了一个 Test
class:
public class Test {
private string nextSync = "N/A";
public string NextSynchronization {
get {
return nextSync;
}
set {
nextSync = value;
}
}
}
并且在 MainWindow
我使用这个:
DataContext = new CScheduler.Test();
似乎已使用 N/A
这只是评论。首先你应该在这一行放置一个断点:
return nextSync;
但我主要想知道的是,为什么您在 "set" 之后没有任何 OnPropertyChanged(您的 class 实现了 INotifyPropertyChanged?):
public string NextSynchronization
{
get
{
return nextSync;
}
set
{
nextSync = value;
OnPropertyChanged("NextSynchronization");
}
public event PropertyChangedEventHandler PropertyChanged;
private void OnPropertyChanged(string propertyName)
{
if (PropertyChanged != null)
{
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
下面是正确设置 DataContext 的示例:
<Window x:Class="TestApplication.TestWindow"
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"
mc:Ignorable="d"
Title="TestWindow" Height="300" Width="300">
<Grid>
<TextBox Text="{Binding Text}"></TextBox>
<CheckBox IsChecked="{Binding IsChecked}"></CheckBox>
<Button Content="{Binding BtnText}"></Button>
</Grid>
public partial class MainWindow : Window
{
//MainWindow.xaml.cs
public MainWindow()
{
InitializeComponent();
//Create a new Instance of your ViewModel
MyViewModelClass viewModel = new MyViewModelClass();
//Set the DataContext (BindingContext (i.e. where to look for the Bindings) to your ViewModel
DataContext = viewModel;
}
}
正在定义您的 ViewModelClass:
public class MyViewModelClass: INotifyPropertyChanged
{
//Add Constructor
public MyViewModelClass()
{
}
private string _text = "sampleText shown in the TextBox";
public string Text
{
get { return _text; }
set
{
nextSync = value;
OnPropertyChanged();//PropertyName will be passed automatically
}
}
private string _isChecked = true;//CheckBox is checked by default
public string IsChecked
{
get { return _isChecked ; }
set
{
nextSync = value;
OnPropertyChanged();//PropertyName will be passed automatically
}
}
private string _btnText = "Click Me";//Text to display on the button
public string BtnText
{
get { return _btnText ; }
set
{
nextSync = value;
OnPropertyChanged();//PropertyName will be passed automatically
}
}
#region Implementation of INotifyPropertyChanged
public event PropertyChangedEventHandler PropertyChanged;
//When using the [CallerMemberName] Attribute you dont need to pass the PropertyName to the method which is pretty nice :D
protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
#endregion Implementation of INotifyPropertyChanged
}
基本上 DataContext
告诉 UI 在哪里寻找绑定。
如果未设置,则在构建时 VisualStuido 中的输出 window 中会显示绑定错误。
更新:
如果使用 UserControls
:
在您放置 xaml 的项目中添加一个名为 UserControls 的文件夹。 在您的 Window:
中为它们添加命名空间xmlns:userControls="clr-namespace:<YourApplicationName>.UserControls"
然后将 UserControl
添加到 MainWindow 的网格中:
<userControls:MyUserControl1></userControls:MyUserControl1>
重点来了:
- 如果您不在 UserControl.xaml.cs 中为 UserControl 设置 DataContext 它将自动使用来自父控件的控件(在您的情况下是 Window)
- 因此,您在 window 或用户控件中获得的所有绑定都放入那个 1 ViewModel
- 只为Window设置
DataContext
。 - 现在应该从该视图模型中获取所有绑定。