Add to Technorati Favorites

DataBinding (часть 2 - метод вынесения контрола)

Опубликовано 8 Дек | Автор LOB
Ключевые слова:, ,

В прошлом уроке, я показывал проблемы Data Binding и одно из решений, этой проблемы. Сегодня мы будем решать эту же задачу. Но совершенно другим способ. Зачем? Просто каждый способ имеет свои достоинства и недостатки. Поэтому иногда будет быстрей и удобней работать с одним методом, а иногда с другим. Тем более, когда у нас есть несколько решений - это говорит о гибкости языка и технологии.

И так, для начала советую прочесть предыдущую статью. Для тех, кто этого делать не хочет, все таки попрошу себя пересилить и прочитать ;)
А кто не помнит, что было в ней напоминаю. Решаем следующую задачу. Мы получается коллекцию классов, которую мы выводим в виде элементов. Затем надо сделать необходимые действия. В нашем примере мы выделяем один из элементов.

И так посмотрим, представление в XAML:


<Grid  x:Name="LayoutRoot" Background="White">
	  <ItemsControl  x:Name="FilmList">
		  <ItemsControl.ItemTemplate>
			  <DataTemplate>
				  <StackPanel  Orientation="Horizontal" Background="Magenta"  Margin="0,5,0,5"  MouseLeftButtonDown="StackPanel_MouseLeftButtonDown" >
					  <Image  Source="{Binding Image}" Width="30" Height="30"  Margin="5" MouseLeftButtonDown="Image_MouseLeftButtonDown"  />
					  <TextBlock  Text="{Binding Title}" Margin="5" />
					  <TextBlock  Text="{Binding Time}" Margin="5" />
					  <TextBlock  Text="{Binding FileSize}" Margin="5" />
				  </StackPanel>
			  </DataTemplate>
		  </ItemsControl.ItemTemplate>
	  </ItemsControl>
  </Grid>

Вынесем повторяющиеся элементы в отдельный контрол, назовем его Item. И так создайте новый UserControl и вынесем в него следующий код:


<UserControl  x:Class="DataBindingExamples.Item"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Width="600">
	  <StackPanel  x:Name="LayoutRoot">
	  <!— НАШ ЭЛЕМЕНТ -->
		  <StackPanel  x:Name="ItemLayout" Orientation="Horizontal"  Background="Magenta" Margin="0,5,0,5"  MouseLeftButtonDown="ItemLayout_MouseLeftButtonDown">
			  <Image  x:Name="FilmImage" Width="30" Height="30"  Margin="5" />
			  <TextBlock  x:Name="TextTitle" Margin="5" />
			  <TextBlock x:Name="TextTime"  Margin="5" />
			  <TextBlock  x:Name="TextFileSize" Margin="5" />
		  </StackPanel>
	  <!— НАШ ЭЛЕМЕНТ -->
	  </StackPanel>
  </UserControl>

Я убрал все бинд выражения, также изменилось событие MouseLeftButtonDown. Теперь этот элемент мы будем размножать, но нам как-то необходимо устанавливайте свойство наших внутренних элементов. Для этого воспользуемся конструктором и будем в него передавать наши параметры. Еще  нам понадобиться событие, которое будет происходить при клике на этот элемент, и его мы в последствии будем вытаскивать наверх, чтобы знать, что данные элемент кликнут. Также мы создадим метод устанавливающий цвет заднего фона для удобства.

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Media.Animation;
using System.Windows.Shapes;

namespace DataBindingExamples
{
    public partial class Item : UserControl
    {
        //событие клика на элемент
        public event EventHandler ItemClick;
        //храним текущий ID записи
        public int CurrentId;

        //Конструтор нашего Item
        public Item( int id, string title, int time, string fileSize, string imageSource )
        {
            //Устанавливаем свойства внутренних контролов и инициализируем переменные
            InitializeComponent();
            ItemLayout.Tag = id;
            TextTitle.Text = title;
            TextTime.Text = time.ToString();
            TextFileSize.Text = fileSize;

            FilmImage.Source = new BitmapImage(new Uri(imageSource));
            CurrentId = id;
        }

        //Метод меняет фон элемента
        public void SetBackground(Color color)
        {
            ItemLayout.Background = new SolidColorBrush(color);
        }

        private void ItemLayout_MouseLeftButtonDown(object sender, MouseButtonEventArgs e)
        {
            //вызваем наше событие клика на элемент
            if (ItemClick != null)
                ItemClick(this, new ItemEventArgs(Convert.ToInt32(((StackPanel)sender).Tag)));
        }
    }

    //Создадим свой класс, чтобы передавать в параметрах ID кликнутого элемента
    public class ItemEventArgs : EventArgs
    {
        public ItemEventArgs(int id)
        {
            ID = id;
        }

        public int ID { get; set; }
    }
}

И так элемент, готов он умеет делать все, что нам надо и теперь его можно использовать.

Создадим на нашей странице StackPanel в коллекцию, которого мы добавим наши Item.

XAML:


<UserControl  x:Class="DataBindingExamples.Page"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  Width="600"  Height="800">
	  <Grid x:Name="LayoutRoot"  Background="White">
		  <StackPanel  x:Name="FilmsItems" />
	  </Grid>
  </UserControl>

Теперь нам необходимо, получить коллекцию классов от нашего вебсервиса, потом пробежать по ней получить коллекцию Item. И ее в свою очередь добавить в коллекцию FilmsItems.

C#:

using System;
using System.Collections.Generic;
using System.Linq;
using System.Net;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Animation;
using System.Windows.Shapes;
using DataBindingExamples.WebSrv;

namespace DataBindingExamples
{
    public partial class Page : UserControl
    {
        public Page()
        {
            InitializeComponent();

            //получаем нашу коллекцию фильмов
            var connector = new MyWebServiceSoapClient();
            connector.GetFimlsCompleted += connector_GetFimlsCompleted;
            connector.GetFimlsAsync();
        }

        void connector_GetFimlsCompleted(object sender, GetFimlsCompletedEventArgs e)
        {
            if (e.Error != null)
                return;

            if (e.Result.Count &gt; 0)
            {
                List list = new List(e.Result);

                //Создаем наши Item  и добавляем в коллекцию FilmsItems
                foreach (Film current in list)
                {
                    Item item = new Item(current.Id, current.Title, current.Time, current.FileSize, current.Image);

                    //Подписываем на событие
                    item.ItemClick += item_ItemClick;
                    FilmsItems.Children.Add(item);
                }
            }
        }
        
        void item_ItemClick(object sender, ItemEventArgs e)
        {
            //бежим по коллекции StackPanel (FilmsItems)
            foreach (UIElement current in FilmsItems.Children)
            {
                //Выделяем текцщий элемент
                if (Convert.ToInt32(((Item)current).CurrentId) == e.ID)
                {
                    ((Item)current).SetBackground(Colors.Red);
                }
                else
                {
                    ((Item)current).SetBackground(Colors.Magenta);
                }
            }
        }
    }
}

И так проверяем, как видим наш элементы правильно отрабатывают, на события клика, и мы можем получать доступ к любым свойствам любых контролов нашего Item. Изменив, идентификатор доступа, либо добавив новый метод.

Удобно или нет, решать вам.
Этот способ дает нам намного больше гибкости и свободы, и не дает никаких ограничений.

Но в тоже время значительно трудоемок, и требует написания большего количества, двух отдельных контролов. Хотя если контрол используется во многих местах, вам все равно лучше его вынести.

Я надеюсь, эта статья помогла вам, более глубже, окунуться в DataBinding и пути решения проблем при работе с ним. Жду ваших вопросов.

Popularity: 91% [?]

Add to zakladki:
3 комментария | Примеры | Вся статья

3 Комментария к статье “DataBinding (часть 2 - метод вынесения контрола)”

  1. DataBinding (часть 2 - метод вынесения контрола) - Территория блога - Территория Silverlight Says:

    [...] DataBinding (часть 2 - метод вынесения контрола) Posted дек 08 2008, 08:50 by СильверРобот Помечено как: Блог, [...]

  2. Привет!

    Почему не используете подсветку для кода??
    Материал хороший, но не читабельный :(

  3. так будет удобней??

Leave a Reply

Ваш Комментарий * [b][/b] - [i][/i] - [u][/u]- [quote][/quote]