DataBinding - jak działa

0

Witam.

Bawię się DataBinding w WinFormsach.
Niby działa ale... nie wiem jak.
Na formie mam:
ListBox - listBox1
ComboBox - comboBox1
TextBox - tbName

I taki kod:

 public partial class Form1 : Form
    {
        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            List<Person> person = new List<Person>()
                {
                 new Person("John", "Nowak", 30, "accountant", Color.Red, new Font("Meiryo UI", 7.6f)),
                 new Person("Jeremy", "Kowalski", 20, "policeman", Color.Beige, new Font("Magneto", 8)),
                 new Person("Clara", "Wiśniewska", 40, "programmer", Color.Blue, new Font("Mistral", 9)),
                 new Person("Mey", "Kwiatkowska", 50, "unemployed", Color.DarkGray, new Font("Monotype Corsiva", 10.5f))
                };

            listBox1.DataSource = person;
            listBox1.DisplayMember = "NameSurname";

            comboBox1.DataSource = person;
            comboBox1.DisplayMember = "NameSurname";

            tbName.DataBindings.Add(new Binding("Text", person, "Name"));
            tbName.DataBindings.Add(new Binding("Font", person, "Font"));
        }
    }

    class Person
    {
        public Person(string name, string surname, int age, string job, Color color, Font font)
        {
            Name = name;
            Surname = surname;
            Age = age;
            Job = job;
            Color = color;
            Font = font;
        }

        private string _name;
        private string _surname;
        private int _age;
        private string _job;
        private Color _color;
        private Font _font;

        public Font Font
        {
            get { return _font; }
            set { _font = value; }
        }

        public Color Color
        {
            get { return _color; }
            set { _color = value; }
        }
        public string Name
        {
            get { return _name; }
            set { _name = value; }
        }
        public string Surname
        {
            get { return _surname; }
            set { _surname = value; }
        }
        public int Age
        {
            get { return _age; }
            set { _age = value; }
        }
        public string Job
        {
            get { return _job; }
            set { _job = value; }
        }
        public string NameSurname
        {
            get { return _name + " " + _surname; }
        }
    }

Po wybraniu jakiegoś elementu na liście, ten sam element wybierany jest w combo, tbName wypełniany jest odpowiednią wartością i ustawiana jest odpowiednia czcionka.

I tu pojawia się pytanie jak to działa skoro bindowanie ustawione jest na liście a nie na kontrolce.
Skąd lista "wie" jaki element został wybrany w combo (nie ma chyba żadnej właściwości typu "selectedItem") i w jaki sposób "informuje" o tym zbindowane elementy?

0

A w propertisach nie masz jakoś powiązanych wszystkich elementów?

0

@Phoryn nie, nic takiego nie robiłem.

3

Wszystkie kontrolki współdzielą wspólny BindingContext - https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.bindingcontext?view=netcore-3.1
BindingContext można traktować jak statyczny słownik obiektów na BindingManager https://docs.microsoft.com/en-us/dotnet/api/system.windows.forms.bindingmanagerbase?view=netcore-3.1

Wszystkie zbindowane do "person" kontrolki korzystają ze wspólnego "BindingContext[person]" i ComboBox automatycznie odczytuje i aktualizuje tam pozycję, możesz ją sprawdzić w ten sposób:

MessageBox.Show(this.BindingContext[person].Position.ToString());

nie powiem że jest w tym dużo magii i ogólnie nigdy nie lubiłem data bindingu w winformsach. Szczerze to nawet nie wiem jak zrobić na jednej formatce dwie grupy z oddzielnie wybranymi pozycjami - pewnie się da ale nigdy tego na szczęście nie potrzebowałem

// tu znalazłem jeszcze artykuł na ten temat
https://www.codemag.com/Article/0409041/A-Look-Under-the-Hood-of-Windows-Forms-Data-Binding

1

EDIT: @hipekk - ten post dotyczy WPF, pomyliłem technologie ;)

W ostatnich kilku wydaniach magazynu "Programista" był cykl "WPF deep dive" tam było wytłumaczone całkiem sporo smaczków, polecam ;)

Nigdy nie pracuj na "code behind" czyli pliku xaml.cs, chyba, że na prawdę musisz. Poczytaj o konwerterach, wzorcach: ObservableObject, MVVM, command itp.
Największą zaletą xaml-a jest jego całkowita deklaratywność, cały binding można zrobić na konstrukcjach typu:

<ComboBox ItemsSource="{Binding Persons}" SelectedItem="{Binding Person}" />

Jest masa właściwości bindingu i różne składnie: możesz się odnosić do innych kontrolek w pliku, zmieniać dataContext na konkretny obiekt, odnosić się do code behind, ustawić kierunki wiązania, konwertery, triggery.

Kolejna sprawa to obsługa ComboBox i ListBox najlepiej zbindować listę do ItemsSource, a następnie SelectedItem do property w view model. W takim przypadku w property będziesz mieć na bieżąco aktualizowaną wybraną z listy instancję.

Najlepszy tutorial do WPF jaki znalazłem w necie, niestety i tak brakuje w nim wielu ważnych tematów: https://www.wpf-tutorial.com/list-controls/listbox-control/

Uważam, że WPF jest trudny i ogarnięcie go w dobrym stopniu jest sporym wyzwaniem, sam mam dalej z nim spore problemy i za każdym razem odkrywam coś nowego.

1 użytkowników online, w tym zalogowanych: 0, gości: 1