Изграждане на графичен потребителски интерфейс с Windows Forms



страница12/16
Дата27.09.2016
Размер1.09 Mb.
#10985
1   ...   8   9   10   11   12   13   14   15   16

Свързване на данни


Свързването на данни (Data Binding) осигурява автоматично прехвърляне на данни между контроли и източници на данни. Можем например да свържем масив, съдържащ имена на градове с ComboBox контрола и име­на­та от масива ще се показват в нея.

При добавянето на свързване указваме свойството на контролата, което ще свързваме с данните, източника на данните и път до списък или свой­ство на източника, към което ще се свържем. Този път може да е име на свойство, йерархия от имена разделени с точки или празен низ. Ако пътят е празен низ ще се извика метода ToString() на обекта използван като източник на данни.





Свързването на данни е еднопосочно – от контролата към източника на данни!

Промяна на дадено свързано свойство от дадена контрола, променя дан­ни­­те в източника, към който то е свързано. Обратното не е вярно. При про­мя­на на източника на данни, свързаните към него контроли не си про­ме­нят свойствата.

Ако сме променили данните в източника на данни и искаме да отразим промените в свързаните с него контроли, трябва първо да премахнем (изтрием) свързването и след това да го добавим отново.


Източници на данни


Като източник на данни можем да използваме всеки клас или компонент, който имплементира интерфейса IList. Такива са масивите и колекциите. За източници на данни можем да използваме и класове или компоненти, които имплементират интерфейса IBindingList. Този интерфейс поддър­жа нотификация за промяна на данните. IBindingList интерфейсът се имплементира от класа DataView (вж. темата за ADO.NET [TODO: link]).

Контроли, поддържащи data binding


Всички Windows Forms контроли поддържат data binding. Можем да свър­жем което и да е свойство на контрола към източник на данни.

Видове свързване


В Windows Forms имаме два типа свързване на данни:

  • Просто свързване (simple binding) – свързване на контрола с еди­ни­чен обект или единичен (текущ) елемент от списък. Такова свър­зва­не използваме обикновено с контроли като TextBox и CheckBox, кои­то показват единична стойност.

  • Сложно свързване (complex binding) – свързване на списъчна кон­трола със списък. Такова свързване използваме с контроли като ListBox, ComboBox и DataGrid. При него се поддържа текущо избран (активен) елемент от списъка.

Просто свързване


Чрез следващите фрагменти код ще илюстрираме как се осъществява просто свързване на данни в зависимост от източника на данни.

Свързване на контрола към обект


Нека имаме клас Customer, който има свойство Name и TextBox контрола с име TextBoxName. Свързването на свойството Text на TextBox контролата към свойството Name на обект от тип Customer се извършва по следния начин:

class Customer

{

private string mName;



public string Name

{

get { return mName; }



set { mName = value; }

}

}


Customer cust = new Customer();

cust.Name = "Бай Иван";


TextBoxName.DataBindings.Add(new Binding("Text", cust, "Name"));

Използвахме колекцията DataBindings на класа Control. В нея можем да добавяме Binding обекти, които указват кое свойство на текущата кон­трола с кое свойство на дадена друга контрола да бъде свързано. В нашия случай при промяна на TextBoxName.Text ще се променя и свойството Name на свързания обект cust.

Свързване на контрола към списък


Нека имаме масив towns, съдържащ имена на градове, и TextBox контрола с име TextBoxTowns. Свързването на свойството Text на TextBox контро­ла­та към масива с имена на градове се извършва по следния начин:

string[] towns = {"София", "Пловдив", "Варна"};

TextBoxTowns.DataBindings.Add(new Binding("Text", towns, ""));



Оставили сме пътят до свойството на източника, към което ще се свържем, да е празен низ, защото в случая искаме да се свържем свойството Text директно с елементите на масива, който използваме като източник на данни, а не с тяхно свойство. При това свързване текстовата контрола ще се свърже първоначално с първия елемент от масива (символният низ "София"), но след това програмно може да се укаже промяна на текущия елемент и свързването да се промени към някой друг от елементите на масива. На начините за промяна на текущия елемент на свързването ще се спрем след малко.

Свързване на контрола към таблица


Нека имаме DataSet обект ds с таблица Towns с колони id и name и TextBox контрола с име TextBoxTowns. Свързването на свойството Text на TextBox контро­ла­та към колоната name от таблицата може да се извърши по следния начин:

// Create a DataTable with columns id and name

DataTable towns = new DataTable("Towns");

towns.Columns.Add(new DataColumn("id", typeof(int)));

towns.Columns.Add(new DataColumn("name", typeof(string)));


// Add three rows to the table

DataRow row;


row = towns.NewRow();

row["id"] = 1;

row["name"] = "София";

towns.Rows.Add(row);


row = towns.NewRow();

row["id"] = 2;

row["name"] = "Пловдив";

towns.Rows.Add(row);


row = towns.NewRow();

row["id"] = 3;

row["name"] = "Варна";

towns.Rows.Add(row);


// Create a DataSet and add the table to the DataSet

DataSet ds = new DataSet();

ds.Tables.Add(towns);
TextBoxTowns.DataBindings.Add(

new Binding("Text", ds, "Towns.name"));



За да укажем, че искаме да свържем свойството Text на TextBox контро­лата с колоната name на таблицата Towns от източника на данни ds, зада­ваме "Towns.name" за път до свойството на източника. Текстовото поле ще бъде свързано първоначално с първия ред на таблицата и по-точно с полето name от този ред, но по-късно текущият ред може да бъде проме­нен програмно.

Просто свързване с VS.NET


Свързването може да става и по време на дизайн в редактора на VS.NET, ако за източник на данни използваме DataSet. За целта от прозореца Properties на редактора избираме Databindings | Advanced. Появява се прозореца Advanced Data Binding. В него виждаме списък от свойствата на контролата. Намираме свойството за което искаме да добавим свърз­ване и от падащия списък в дясно от него избираме източника на данни.


Свързване на контрола към обект – пример


С настоящия пример ще илюстрираме простото свързване (simple binding) в Windows Forms. За целта ще създадем просто приложение, в което ще свържем свойство на контрола със свойство на даден обект.

Ето стъпките за изграждане на нашето приложение:



  1. Стартираме VS.NET и създаваме нов Windows Forms проект.

  2. Задаваме на главната форма име MainForm и заглавие "Binding Control To Object". Променяме и името на файла от Form1.cs на MainForm.cs.

  3. Дефинираме клас Customer, с чийто обект ще свържем по-късно контро­лата. Класът има свойство Name, даващо достъп до името на клиента:

    class Customer

    {

    private string mName;



    public string Name

    {

    get { return mName; }



    set { mName = value; }

    }

    }



  4. Добавяме в класа MainForm една член променлива mCustomer. С нея ще свържем текстово поле във формата.

    private Customer mCustomer;

  5. В главната форма поставяме една TextBox контрола с име TextBoxCustomerName, която ще свържем с Customer обекта и три бутона с имена ButtonShowCustomer, ButtonChangeCustomer и ButtonRebind. Тези бутони ще служат съответно за показване на името на клиента, за промяна на името и за извършване на свърз­ва­не (data binding) на текстовото поле с Customer обекта.

  6. В класа MainForm добавяме функция RebindFormControls(), която свързва свойството Text на текстовата контрола със свойството Name на Customer обекта. За целта първо свързването се изтрива (в случай че е било вече създадено) и след това се добавя отново:

    private void RebindFormControls()

    {

    TextBoxCustomerName.DataBindings.Clear();



    TextBoxCustomerName.DataBindings.Add(

    new Binding("Text", mCustomer, "Name"));

    }


  7. Добавяме код, който при зареждане на формата (при събитие Load на формата) да инициализира Customer обекта и да го свърже с текстовата контрола:

    private void MainForm_Load(object sender, System.EventArgs e)

    {

    mCustomer = new Customer();



    mCustomer.Name = "Бай Иван";
    RebindFormControls();

    }


  8. Добавяме обработчик на събитието Click на ButtonShowCustomer бутона. В него извличаме стойността на полето Name на Customer обекта и я показваме в диалогова кутия:

    private void ButtonShowCustomer_Click(object sender,

    System.EventArgs e)

    {

    string customerName = mCustomer.Name;



    MessageBox.Show(customerName);

    }


  9. Добавяме обработчик на събитието Click на ButtonChangeCustomer бутона. В него променяме стойността на полето Name на Customer обекта:

    private void ButtonChangeCustomer_Click(object sender,

    System.EventArgs e)

    {

    mCustomer.Name = "Дядо Мраз";



    }

  10. Добавяме обработчик на събитието Click на бутона ButtonRebind. В него извикваме функцията RebindFormControls(), която извър­шва повторно свързване на текстовата контрола с името на клиента от Customer обекта, при което това име се появява в контролата:

    private void ButtonRebind_Click(object sender,

    System.EventArgs e)

    {

    RebindFormControls();



    }

  11. Приложението вече е готово и можем да го стартираме и тестваме.

Ако въведем стойност в полето и натиснем първия бутон, в диалоговата кутия ще се покаже въведената стойност. Това показва, че стойността се е прехвърлила в Customer обекта:

Ако натиснем втория бутон, стойността в Customer обекта ще се промени. Това можем да проверим като натиснем първия бутон и изведем стойност­та в диалогова кутия. Въпреки че стойността в Customer обекта е променена, текстовото поле не се променя. Това е така, защото свързва­не­то в Windows Forms е еднопосочно – от контролата към свързвания обект, но не и обратно.

Ако сега натиснем третия бутон, текстовото поле ще се промени. Това е така, защото извършваме повторно свързване и името на клиента от Customer обекта се прехвърля в текстовото поле.

Binding Context


Формата пази информация за свързаните контроли в своя BindingContext обект. Всеки обект, наследен от класа Control има един BindingContext, който управлява BindingContextBase обектите за контролите, които се съдържат в него и за самия обект. Чрез него можем да извлечем BindingContextBase обект за източник на данни, свързан с някоя кон­тро­ла.

Понеже BindingContextBase е абстрактен клас, типът на върна­та­та стойност, в зависимост от източника на данни, е или CurrencyManager или PropertyManager, които са на­след­ни­ци на класа BindingContextBase. Ако източникът на данни е обект, който връща само една стойност (не е спи­сък от обекти), тогава типът ще бъде PropertyManager. Ако източникът на данни имплементира някой от интерфейсите IList, IListSource или IBindingList, ще бъде върнат CurrencyManager.

На следващата фигура са показани схематично отношенията между Binding Context, Currency Manager и Property Manager:


Навигация с CurrencyManager


Класът CurrencyManager пази текущата позиция в списъка-източник на дан­ни. Тя се съдържа в свойството Position. Свойството Count съдържа размера на списъка. Използвайки тези свойства, можем да извършваме навигация по източника на данни. За целта извличаме CurrencyManager обекта, свързан с източника на данни и променяме стойността на свой­ство­то Position.

Извличането на CurrencyManager обекта се извършва или чрез свойството DataBindings на свързаната контрола, или чрез BindingContext свойство­то на фор­ма­та:



CurrencyManager cm = (CurrencyManager)

textBox1.DataBindings["Text"].BindingManagerBase;


// Може и така:

CurrencyManager cm = (CurrencyManager)

form1.BindingContext[dataTableCustomers];


Навигацията по списъка се извършва чрез промяна на Position:

cm.Position++;

Свързване на контрола към списък и навигация – пример


С настоящия пример ще илюстрираме просто свързване (simple binding) на контрола към списък и навигация по списъка чрез CurrencyManager.

Ето стъпките за изграждане на приложението:



  1. Стартираме VS.NET и създаваме нов Windows Forms проект.

  2. Задаваме на главната форма име MainForm и заглавие "Binding Control To List". Променяме и името на файла от Form1.cs на MainForm.cs.

  3. Поставяме върху главната форма една TextBox контрола с име TextBoxTowns, която ще свържем с масив от символни низове - имена на градове и два бутона с имена ButtonPrev и ButtonNext. Тези бутони ще служат съответно за навигация напред и назад по списъка с градовете. На свойството Text на двата бутона задаваме съответно стойности "<< Prev" и "Next >>".

  4. Добавяме код, който при зареждане на формата (при събитие Load на формата) свързва текстовото поле с масив съдържащ имена на градове:

    private void MainForm_Load(object sender, System.EventArgs e)

    {

    string[] towns = {"София", "Пловдив", "Варна",



    "Русе", "Бургас"};

    TextBoxTowns.DataBindings.Add(

    new Binding("Text", towns, ""));

    }


  5. Добавяме обработчик на събитието Click на бутона ButtonPrev. В него извличаме от CurrencyManager обекта на текстовата контрола теку­щата позиция в списъка с градовете и я намаляваме като, ако сме достигнали началото, позиционираме в края:

    private void ButtonPrev_Click(object sender, System.EventArgs e)

    {

    CurrencyManager cm = (CurrencyManager)



    TextBoxTowns.DataBindings["Text"].BindingManagerBase;

    if (cm.Position > 0)

    {

    cm.Position--;



    }

    else


    {

    cm.Position = cm.Count-1;

    }

    }


  6. Добавяме обработчик на събитието Click на бутона ButtonNext. В него извличаме от CurrеncyManager на текстовата контрола теку­щата позиция в списъка с градовете и я увеличаваме като, ако сме достигнали края, позиционираме в началото:

    private void ButtonNext_Click(object sender, System.EventArgs e)

    {

    CurrencyManager cm = (CurrencyManager)



    TextBoxTowns.DataBindings["Text"].BindingManagerBase;

    if (cm.Position < cm.Count-1)

    {

    cm.Position++;



    }

    else


    {

    cm.Position = 0;

    }

    }


  7. Приложението е готово и можем да го стартираме и тестваме.

При натискане на бутоните в текстовото поле ще се сменят имената на градовете. Ако променим името на някой град, промяната се отразява в масива с имената.


Сложно свързване


При сложното свързване имаме свързване на контрола към списък, като контролата се свързва с повече от един елемент от списъка. Сложното свързване се използва при списъчни контроли – ListBox, ComboBox и др.

За да свържем списъчна контрола със списък, трябва да зададем стой­ност­и на следните свойства:



  • DataSource – източника на данни с който ще свържем контролата.

  • DisplayMember – път до полето, което да се визуализира.

  • ValueMember – път до полето, от което се получава резултата.

Стойността по подразбиране в DisplayMember и ValueMember е празен низ.

Ето как задаваме стойност на тези свойства:



Dataset dataSetCountries = ...;

comboBox1.DataSource = dataSetCountries;

comboBox1.DisplayMember = "Countries.CountryCode";

comboBox1.ValueMember = "Countries.Name";


Сложно свързване на контрола към списък – пример


С настоящия пример ще илюстрираме сложното свързване (complex data binding) в Windows Forms. За целта ще създадем просто приложение, в което ще свържем списъчна контрола със списък.

Ето стъпките за изграждане на нашето приложение:



  1. Стартираме VS.NET и създаваме нов Windows Forms проект.

  2. Задаваме на главната форма име MainForm и заглавие "Complex Binding". Променяме името на файла от Form1.cs на MainForm.cs.

  3. Поставяме във формата един бутон с име ButtonShow и една ComboBox контрола с име ComboBoxTowns. На свойството Text на бутона задаваме стойност Show. ComboBox контролата ще свържем с масив от символни низове - имена на градове, а чрез бутона ще показваме стойността избрана в нея.

  4. Добавяме код, който при зареждане на формата (при събитие Load) свързва ComboBox контролата с масив, съдържащ имена на градове:

    private void MainForm_Load(object sender, System.EventArgs e)

    {

    string[] towns = {"София", "Пловдив", "Варна",



    "Русе", "Бургас"};

    ComboBoxTowns.DataSource = towns;

    ComboBoxTowns.DisplayMember = "";

    }


  5. Добавяме обработчик на събитието Click на бутона ButtonShow. В него показваме в диалогова кутия стойността, избрана в ComboBox контролата:

    private void ButtonShow_Click(object sender, System.EventArgs e)

    {

    MessageBox.Show(ComboBoxTowns.SelectedValue.ToString());



    }

  6. Приложението ни е готово и можем да го стартираме и тестваме.


Сложно свързване с VS.NET


Сложното свързване може да става и по време на дизайн в редактора на VS.NET, ако за източник на данни използваме DataSet. За целта в прозо­ре­ца Properties на редактора щракваме в върху падащия списък от дясно на свойството DataSource и избираме от него източник на данни. След това избираме от падащите списъци в дясно от свойствата DisplayMember и ValueMember полето, което ще се визуализира и полето от което ще се получава резултата:





Сподели с приятели:
1   ...   8   9   10   11   12   13   14   15   16




©obuch.info 2024
отнасят до администрацията

    Начална страница