Я новичок в WPF, и я пытаюсь сделать то, что, по моему мнению, было бы простой задачей - отобразить значение поля в моем бизнес-объекте по мере его изменения во время моей программы.Я знаю, как «заставить» его изменить, вручную изменив свойство TextBox.Text в C #, но, изучая WPF, я хочу сделать это «правильным» способом, а это означает привязку данных.
Вопрос № 1: Насколько я понимаю, я выбрал либо использование DependencyProperty, либо реализацию INotifyPropertyChanged в моем бизнес-объекте, верно?
Вопрос № 2: Вот общая версия моего кода, в которой я попытался перейти по маршруту DependencyProperty.
Разметка:
Button x:Name="nextButton" Content="Click" Grid.Row="2" Click="nextButton_Click" />
TextBox x:Name="myTextBox" Grid.Row="1" Text="{Binding Source=myTest, Path=Name, UpdateSourceTrigger=PropertyChanged, NotifyOnSourceUpdated=True}"/>
Код позади:
namespace DependencyTest2
{
///
/// Interaction logic for MainWindow.xaml
///
public partial class MainWindow : Window
{
private int i;
private TestSphere myTest;
public MainWindow()
{
InitializeComponent();
i = 0;
myTest = new TestSphere();
}
private void nextButton_Click(object sender, RoutedEventArgs e)
{
switch (i)
{
case 0:
myTest.Name = "string1";
break;
case 1:
myTest.Name = "string2";
break;
case 2:
myTest.Name = "string3";
break;
}
i++;
}
}
class TestSphere : DependencyObject
{
public string Name
{
get { return (string)GetValue(NameProperty); }
set { SetValue(NameProperty, value); }
}
public static readonly DependencyProperty NameProperty =
DependencyProperty.Register("Name", typeof(string), typeof(TestSphere));
public TestSphere()
{
Name = "default";
}
}
}
Когда я запускаю программу, в текстовом поле ничего не появляется, даже если свойство bound имеет значение- Есть ли что-то еще, что мне нужно сделать, чтобы предупредить привязку об изменении исходного значения?Я думал, что использование DependencyProperty в качестве источника позаботится об этом, но опять же, я новичок WPF.Спасибо!
Хорошо, я попытался реализовать INotifyPropertyChanged, используя класс-оболочку, который я нашел в codeproject, следующим образом:
class TestSphere : NotifyProperyChangedBase
{
private string _Name;
public string Name
{
get { return _Name; }
set
{
this.CheckPropertyChanged("Name", ref _Name, ref value);
}
}
public TestSphere()
{
Name = "default";
}
}
public abstract class NotifyProperyChangedBase : INotifyPropertyChanged
{
#region INotifyPropertyChanged Members
public event PropertyChangedEventHandler PropertyChanged;
#endregion
#region methods
protected bool CheckPropertyChanged(string propertyName, ref T oldValue, ref T newValue)
{
if (oldValue == null && newValue == null)
{
return false;
}
if ((oldValue == null && newValue != null) || !oldValue.Equals((T)newValue))
{
oldValue = newValue;
FirePropertyChanged(propertyName);
return true;
}
return false;
}
protected void FirePropertyChanged(string propertyName)
{
if (this.PropertyChanged != null)
{
this.PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
}
#endregion
Вотмоя новая разметка тоже:
Grid Name="myGrid">
Grid.RowDefinitions>
RowDefinition Height="30"/>
RowDefinition Height="30"/>
RowDefinition Height="30"/>
RowDefinition Height="*"/>
/Grid.RowDefinitions>
Label x:Name="myLabel" Grid.Row="0" Foreground="Black" />
Button x:Name="nextButton" Content="Click" Grid.Row="2" Click="nextButton_Click" />
TextBox x:Name="myTextBox" Grid.Row="1" Text="{Binding Path=myTest.Name}"/>
/Grid>
Я также добавил строку myGrid.DataContext = myTest;
в 'public MainWindow ()' сразу после того, как создал экземпляр myTest.Когда я выполняю пошаговую программу, значение this.PropertyChanged
всегда оценивается как null
, так что PropertyChanged даже никогда не срабатывает.Заранее извините за то, что, должно быть, действительно нубский вопрос.