Wpf: binding data from an object
There is a separate class Piple
with a bunch of data about a person, I create an object of this class in MainWinow
. In the main window of the application, I have a lot of different texboxes for this object (first name, last name, etc.). Is it possible to somehow use Binding
, to make it so that when changing the object, the data in the corresponding textbox,
would change and vice versa, when changing in textbox
, the corresponding fields in Piple
would change?
Here is the class code Piple
:
namespace WpfApplication4
{
public class Piple
{
public string name;
public string name2;
public Piple()
{
name="Иван";
name2="Иванов";
}
}
}
Main class code C#:
namespace WpfApplication4
{
/// <summary>
/// Логика взаимодействия для MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
Piple chel = new Piple();
public MainWindow()
{
InitializeComponent();
this.DataContext = this;
}
}
}
Window code in XAML
<Window x:Class="WpfApplication4.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="350" Width="525" WindowState="Maximized">
<Grid >
<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" Margin="28,76,0,0" RenderTransformOrigin="0.5,0.5"/>
<TextBox HorizontalAlignment="Left" Height="23" TextWrapping="Wrap" Text="" VerticalAlignment="Top" Width="120" Margin="28,135,0,0"/>
</Grid>
</Window>
You need to bind the data from chel.name
and chel.name2
to the corresponding textbox
, respectively. Can you tell me if this can be done with Binding
?
1 answers
- Binding to class fields in WPF is not possible, you need at least properties (property).
- In order for the new values to be displayed in the control when the class properties are changed, the class must inherit from the INotifyPropertyChanged interface
- You yourself did not register bindings for textboxes.
It should all look something like this:
public class People : INotifyPropertyChanged // Наследуемся от нужного интерфеса
{
// Ваши поля
private string name, name2;
public event PropertyChangedEventHandler PropertyChanged; // Событие, которое нужно вызывать при изменении
// Для удобства обернем событие в метод с единственным параметром - имя изменяемого свойства
public void RaisePropertyChanged(string propertyName)
{
// Если кто-то на него подписан, то вызывем его
if (PropertyChanged != null)
PropertyChanged(this, new PropertyChangedEventArgs(propertyName));
}
// А тут будут свойства, в которые мы обернем поля
public string Name
{
get { return name; }
set
{
// Устанавливаем новое значение
name = value;
// Сообщаем всем, кто подписан на событие PropertyChanged, что поле изменилось Name
RaisePropertyChanged("Name");
}
}
public string Name2
{
get { return name2; }
set
{
// Устанавливаем новое значение
name2 = value;
// Сообщаем всем, кто подписан на событие PropertyChanged, что поле изменилось Name2
RaisePropertyChanged("Name2");
}
}
}
In the control code, we create an instance of the class and write the DataContext (in fact, the DataContext can be written in marking up the control):
public MainWindow()
{
// Создаем экземпляр нашего класса
P = new People(){Name = "Ololosha", Name2 = "Trololosha"};
InitializeComponent();
// Устанавливаем как контекст данных
DataContext = P;
}
And in the markup of the control, we write textboxes:
<TextBox Text="{Binding Path=Name}"/>
<TextBox Text="{Binding Path=Name2}"/>
Now it will work the way you want it to.
Perhaps we should also mention such a binding property as UpdateSourceTrigger
. It describes when to change the source. By default, the textbox has the value LostFocus
, i.e. the change will occur only when the TextBox loses focus. If you want the changes to happen immediately, then you need to UpdateSourceTrigger
set to PropertyChanged
:
<TextBox Text="{Binding Path=Name2, UpdateSourceTrigger=PropertyChanged}"/>
I would I advised you to find a good book on WPF. Here there is a pretty good site about WPF (and not only about it), at least it helped me a lot at the time