绑定不在另一个类

时间:2016-10-28 14:43:56

标签: c# wpf class xaml binding

textBox绑定另一个类中的logContent。 如果我在MainWindow中更改变量logContent的值,则所有工作正常。但是,如果我在Test.cs中更改变量logContent的值(当我点击按钮时)它不起作用。

MainWindow.cs

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        textBox.DataContext = Log.Instance;
        Log.Instance.logContent += "aaa" + Environment.NewLine; //this working
    }

    private void button_Click(object sender, RoutedEventArgs e)
    {
        Test.Instance.Volaj();
    }
}

Log.cs

class Log
{
    public string logContent { get; set; }

    private static Log instance;
    public static Log Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Log();
            }
            return instance;
        }
    }
}

test.cs中

class Test
{
    private static Test instance;
    public static Test Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Test();
            }
            return instance;
        }
    }

    public void Volaj()
    {
        Log.Instance.logContent += "bbb" + Environment.NewLine; //not working
    }
}

textBox的XAML

<TextBox 
x:Name="textBox" 
HorizontalAlignment="Left" 
Height="154" 
Margin="10,155,0,0" 
TextWrapping="Wrap" 
Text="{Binding logContent}" 
VerticalAlignment="Top" 
Width="497"/>

1 个答案:

答案 0 :(得分:0)

在您的代码中,DataBinding无法在任何类中运行。

您可以通过这个简单的测试看到这一点(您必须在MainWindow.xaml中添加Loaded-Event):

public MainWindow()
{
    InitializeComponent();
    textBox.DataContext = Log.Instance;
    Debug.WriteLine($"Text [ctor before change]: {textBox.Text}");
    // Output:
    Log.Instance.logContent += "aaa" + Environment.NewLine; //this working
    Debug.WriteLine($"Text [ctor after change]: {textBox.Text}");
    // Output:
}

private void button_Click(object sender, RoutedEventArgs e)
{
    Test.Instance.Volaj();
}

private void MainWindow_OnLoaded(object sender, RoutedEventArgs e)
{
    Debug.WriteLine($"Text [Loaded before change]: {textBox.Text}");
    // Output: aaa
    Log.Instance.logContent += "bbb" + Environment.NewLine;
    Debug.WriteLine($"Text [Loaded after change]: {textBox.Text}");
    // Output: aaa
}

TextBox.Text属性在构造函数期间不会更改。构造函数完成后,视图将读取DataContext一次并更新其Text属性。这就是您在TextBox中看到文本的原因。当触发Loaded-Event时,TextBox已经具有文本值。其他更改将不会显示。

要使绑定工作,您必须通知视图,属性已更改。出于这个原因,存在INotifyPropertyChanged-Interface。因此,如果您将Log.cs更改为以下内容,它应该可以工作:

class Log : INotifyPropertyChanged
{
    private string _logContent;

    public string logContent
    {
        get { return _logContent; }
        set { _logContent = value; OnPropertyChanged(); }
    }

    private static Log instance;
    public static Log Instance
    {
        get
        {
            if (instance == null)
            {
                instance = new Log();
            }
            return instance;
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}