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"/>
答案 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));
}
}