środa, 19 grudnia 2012

70-511 Rozdział 7 - Binding - bindowanie do różnych typów cz. 2

Bindowanie do obiektów ADO.NET
Najczęściej obiekty ADO.NET inicjuje się w kodzie, a następnie w XAMLu następuje bindowanie do konkretnej kontrolki.

DataTable
DataTable generujemy w kodzie, następnie przypisujemy go do DataContext. Bindowanie następuje bez podania parametru - chyba że bindujemy się do ViewModel - wtedy podajemy nazwę właściwości, która zwraca DataTable. Na koniec we właściwości DisplayMemberPath wpisujemy kolumnę która ma być wyświetlana. 
Jeżeli chcemy się zbindować do kontrolki typu Content, podajemy nazwę kolumny, której wartość chcemy wyświetlić.

DataSet
DataSet to kolekcja obiektów DataTable - wraz ze zdefiniowanymi kluczami oraz połączeniami pomiędzy tymi obiektami. 
Bindując się do kontrolki listowej w ścieżce (Path) podajemy nazwę tabli, której zawartość chcemy wyświetlić. Tak jak poprzednio w DisplayMemberPath podajemy kolumnę której zawartość chcemy wyświetlić.

W przypadku bindowania do kontrolki typu Content, należy podać w ścieżce zarówno nazwę tabli do której się bindujemy jak i nazwę kolumny wg wzoru:
NazwaTabeli/Kolumna

Przykład obrazujący te dwa bindowania:

Code:
        public MainWindow()
        {
            InitializeComponent();
            grdDataTable.DataContext = new DataService().GetCustomersDataTable();
            grdDataSet.DataContext = new DataService().GetDataSet();
        }

Code:
<Window x:Class="Binding_AdoNet.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">
    <Grid>
        <Grid.ColumnDefinitions>
            <ColumnDefinition />
            <ColumnDefinition />
        </Grid.ColumnDefinitions>
        <Grid Name="grdDataTable">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition Height="20"></RowDefinition>
            </Grid.RowDefinitions>
            <ListBox ItemsSource="{Binding}" DisplayMemberPath="FirstName" />
            <TextBlock Grid.Row="1" Text="{Binding LastName}"></TextBlock>
        </Grid>
        <Grid Name="grdDataSet" Grid.Column="1">
            <Grid.RowDefinitions>
                <RowDefinition></RowDefinition>
                <RowDefinition Height="20"></RowDefinition>
            </Grid.RowDefinitions>
            <ListBox ItemsSource="{Binding Customer}" DisplayMemberPath="LastName" Grid.Column="1" />
            <TextBlock Grid.Row="1" Text="{Binding Customer/FirstName}"></TextBlock>
        </Grid>
    </Grid>
</Window>

Kod w całości znajduje się pod adresem: http://sdrv.ms/12nnaRd

Efekt powyższego kodu:




Bindowanie do danych hierarchicznych
Dane hierarchiczne to np. hierarchie klas można w taki sam sposób jak dane z DataSet-u wyświetlać na kilku listach, a dzięki synchronizacji pomiędzy nimi, implementacja rozwiązania opartego o nagłówki i szczegóły staje się bardzo proste.
Przykład:

Code:
<Window x:Class="HierarchicalData.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">
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="30"/>
        </Grid.RowDefinitions>
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>
        
        <ListBox ItemsSource="{Binding}" Grid.Column="0" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="CustomerID" />
        <ListBox ItemsSource="{Binding SalesOrderHeaders}" Grid.Column="1" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="SalesOrderID" />
        <ListBox ItemsSource="{Binding SalesOrderHeaders/SalesOrderDetails}" Grid.Column="2" IsSynchronizedWithCurrentItem="True" DisplayMemberPath="SalesOrderDetailID" />
        
        <TextBlock Grid.Column="0" Grid.Row="1" TextAlignment="Center" Text="{Binding FirstName}" />
        <TextBlock Grid.Column="1" Grid.Row="1" TextAlignment="Center" Text="{Binding SalesOrderHeaders/OrderDate}" />
        <TextBlock Grid.Column="2" Grid.Row="1" TextAlignment="Center" Text="{Binding SalesOrderHeaders/SalesOrderDetails/UnitPrice}" />
    </Grid>
</Window>

Efekt:


Cały kod można pobrać z serwera: http://sdrv.ms/SVyQXb




ObjectDataProvider
Obiekt ten pozwala na bindowanie elementu do metody obiektu. Dzięki temu możemy w XAML-u podać typ obiektu oraz metodę której rezultat ma zostać użyty w procesie bindowania.
Właściwości z których możemy skorzystać w ObjectDataProvider:
  • ConstructorParameters - parametry przesłane do kontruktora
  • IsAsynchronous - czy tworzenie obiektu lub wywołanie metody jest na innym wątku
  • MethodName - nazwa metody
  • MethodParameters - parametry metody
  • ObjectInstance - obiekt użyty do bindowania
  • ObjectType - typ obiektu, który ma być stworzony
Bindowanie nie może uaktualniać danych w źródle - jest więc tylko w jedną stronę.
Przykład:

Code:
<Window x:Class="Binding_ObjectDataProvider1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:binidngObjectDataProvider="clr-namespace:Binidng_ObjectDataProvider" Title="MainWindow" Height="350" Width="525">
    <Window.Resources>
        <ObjectDataProvider x:Key="odpCustomers" ObjectType="{x:Type binidngObjectDataProvider:DataService}" MethodName="GetCustomersByFirstName" />
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource odpCustomers}}" DisplayMemberPath="FirstName"></ListBox>
    </Grid>
</Window>

DataService:

Code:
using System.Collections.Generic;
using System.Linq;
using Binding_ObjectDataProvider1;

namespace Binidng_ObjectDataProvider
{
    public class DataService
    {
        private readonly AdventureWorksLTEntities context = new AdventureWorksLTEntities();

        public DataService()
        {

        }

        public IList<Customer> GetCustomersByFirstName()
        {
            var result = context.Customers.ToList();

            return result.ToList();
        }
    }
}


Kod całego programu do pobrania tutaj: http://sdrv.ms/UhupoT



XmlDataProvider
Provider ten oferuje bindowanie do danych w formacie XML.
Ważniejsze właściwości:
  • Document - obiekt typu XmlDocument, służący jako źródło danych
  • Source - ścieżka do pliku XML
  • XPath - zapytanie XPath
Przykład bindowania:

Code:
<Window x:Class="Binding_XmlDataProvider.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">
    <Window.Resources>
        <XmlDataProvider x:Key="sampleData" Source="SampleXml.xml" />
    </Window.Resources>
    <Grid>
        <ListBox ItemsSource="{Binding Source={StaticResource sampleData}, XPath=catalog/book/title}"></ListBox>
    </Grid>
</Window>

Właściwość XPath można ustawić zarówno na providerze jak i podczas bindowania (druga opcja widoczna na powyższym kodzie).

Źródła programu wraz z przykładowym plikiem XML do pobrania: http://sdrv.ms/UY6DRA

Brak komentarzy:

Prześlij komentarz