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
  • 现在应该从该视图模型中获取所有绑定。