Я новичок в C #, у которого проблемы с пониманием того, почему его первая попытка понять привязки XAML не работает. Я слежу за Microsoft Обзор привязки данных .
У меня есть один TextBox, который в конечном итоге будет служить окном состояния. Сейчас я просто хочу иметь возможность писать произвольные текстовые строки в него. У меня также есть экземпляр шаблона команды, который я тестирую. Моя команда включает в себя добавление случайного числа в аккумулятор и распечатку результата в представлении статуса.
Вот мой XAML для главного окна приложения:
<Window x:Class="Experiment.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:c="clr-namespace:Experiment"
Title="Test" Height="500" Width="700" Name="Test" Closing="Test_Closing" DataContext="{Binding ElementName=statusText}" xmlns:my="clr-namespace:Experiment">
<Window.Resources>
<c:StatusViewText x:Key="statusViewText" />
</Window.Resources>
<DockPanel HorizontalAlignment="Stretch" Margin="0,0,0,0" Width="Auto">
<!-- Elements deleted for brevity. -->
<TextBox Margin="5,5,5,5" Name="statusText" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" AcceptsReturn="True" AcceptsTab="True" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Auto" FontFamily="Courier New" FontSize="12"
Text="{Binding Source={StaticResource statusViewText}, Path=statusTextString, Mode=OneWay}"/>
</DockPanel>
</Window>
И класс, представляющий мои данные:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace Experiment {
public class StatusViewText {
public StringBuilder statusText { get; set; }
public String statusTextString { get; set; }
public StatusViewText() {
statusText = new StringBuilder();
}
public void Append(string s) {
if (s != null) {
statusText.Append(s);
}
statusTextString = statusText.ToString();
}
public void AppendLine(string s) {
if (s != null) {
statusText.AppendLine(s);
}
statusTextString = statusText.ToString();
}
}
}
В конце концов, я буду использовать подходящий конвертер из StringBuilder, но я хотел бы разобраться с принципом, прежде чем исследовать эту сложность.
Если бы мое понимание было правильным (и, очевидно, это не так), это все ДОЛЖНО работать. Назначение привязки - это TextBox, свойство target - свойство Text. Источником привязки является свойство statusTextString класса StatusViewText. Тем не менее, когда я запускаю команду (и отлаживаю и вижу, что StatusViewText.statusTextString обновляется), TextBox не обновляется.
Я подумал, что мне, возможно, потребуется явно добавить привязку самостоятельно, поэтому я попытался добавить это после InitializeComponent()
в конструкторе главного окна:
statusViewText = new StatusViewText();
Binding statusViewTextBinding = new Binding("statusTextString");
statusViewTextBinding.Source = statusViewText;
statusText.SetBinding(TextBlock.TextProperty, statusViewTextBinding);
но это тоже не сработало.
Нужно ли запускать события PropertyChanged? Я думал, что весь смысл связующего фреймворка в том, что события запускаются и потребляются за сценой, автоматически; но может я и там ошибаюсь.
Нет явных ошибок в окне «Вывод», которые заставляют меня поверить, что мой синтаксис привязки правильный; Я просто пропускаю что-то еще.
Halp!
РЕДАКТИРОВАТЬ 13:14 EDT Спасибо mben :
Хорошо, я сделал это. Добавлено следующее:
public class StatusViewText : INotifyPropertyChanged {
public void Append(string s) {
if (s != null) {
statusText.Append(s);
}
statusTextString = statusText.ToString();
NotifyPropertyChanged("statusTextString");
}
public void AppendLine(string s) {
if (s != null) {
statusText.AppendLine(s);
}
statusTextString = statusText.ToString();
NotifyPropertyChanged("statusTextString");
}
public event PropertyChangedEventHandler PropertyChanged;
private void NotifyPropertyChanged(String info) {
if (PropertyChanged != null) {
PropertyChanged(this, new PropertyChangedEventArgs(info));
}
}
}
Я отладил, чтобы убедиться, что он проходил по этому пути кода, и это так. Но все равно не повезло. Есть еще мысли?