WPF绑定 - Lable绑定问题

时间:2016-05-18 12:01:36

标签: c# wpf mvvm datacontext

我试图使用Async DataBinding,因为我需要在我的应用程序上执行必须访问UI控件的多个线程。为此,我已将Label声明为:

<Label x:Name="SyncRange" Content="{Binding NextSynchronization, IsAsync=True}" />

(注意这是我自己的控制),所以在控件的类中我已经定义了这个:

private string nextSync = "N/A";

public string NextSynchronization {
    get {
        return nextSync;
    }
    set {
        nextSync = value;
    }
}

如何看待nextSync的默认值为N/A,我可以从任何类更改变量的值。 此时我已经以这种方式在我的MainWindow中导入了控件:

xmlns:OwnControl="clr-namespace:SynchronizationTool"

并将其用作:

<OwnControl:Scheduler x:Name="Scheduler"/>
当我按下保存按钮时,在MainWindow类中的

我希望在标签中显示一个新值,所以:

private void Save_Click(object sender, RoutedEventArgs e)
{
     Scheduler.NextSynchronization = "test";
}

标签应自动绑定值test,但不幸的是,标签仍为空。我做错了什么?

更新

我已在我的控件中创建了一个Test课程:

public class Test {
    private string nextSync = "N/A";

    public string NextSynchronization {
        get {
            return nextSync;
        }
        set {
            nextSync = value;
        }
    }
}

并在MainWindow我用这个:

DataContext = new CScheduler.Test();

似乎使用N/A

正确初始化了Label

2 个答案:

答案 0 :(得分:2)

这只是一个评论。首先,你应该在这一行上设一个断点:

return nextSync;

但我的主要想知道为什么你的“set”之后没有任何OnPropertyChanged(你的类实现了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));
        }
    }

答案 1 :(得分:2)

以下是正确设置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在哪里寻找Binding。 如果未设置此选项,则构建时VisualStuido中的输出窗口中将显示绑定错误。

<强>更新

如果使用UserControls

在项目中添加一个名为UserControls的文件夹,放置xamls。 在Window中为它们添加命名空间:

xmlns:userControls="clr-namespace:<YourApplicationName>.UserControls"

然后将UserControl添加到MainWindow的网格中:

<userControls:MyUserControl1></userControls:MyUserControl1>

这是重要的部分:

  • 如果您没有在UserControl.xaml.cs中为UserControl设置DataContext 它将自动使用父Control(在您的情况下是Window)
  • 中的一个
  • 因此,您在窗口或用户控件中获得的所有绑定都放入了1 ViewModel
  • 仅为窗口设置DataContext
  • 现在应该从该视图模型中获取所有绑定。