Uno Platform 偵查報告 -- 集合資料繫結

這一篇偵查 Uno Platform 對於集合資料繫結的功能。

Uno.UI version: 1.41.1-dev.134
偵查對象:ObseverableCollection Binding

前一篇我們測試過對於簡單資料繫結的情境,Uno Platform 對於集合資料繫結的支援度又是如何?這一次就試著來繫結 ObserverableCollection<T> 吧。

建立必要的資料類別
    public abstract class NotifyPropertyBase : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;
        protected void SetProperty<T>(ref T storage, T value, [CallerMemberName] string propertyName = null)
        {
            if (!object.Equals(storage, value))
            {
                storage = value;
                PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
            }
        }      
    }

    public class Person : NotifyPropertyBase
    {
       
        private string _name;
        public string Name
        {
            get { return _name; }
            set { SetProperty(ref _name, value); }
        }

        private string _address;
        public string Address
        {
            get { return _address; }
            set { SetProperty(ref _address, value); }
        }

        private int _age;
        public int Age
        {
            get { return _age; }
            set { SetProperty(ref _age, value); }
        }      
    }

    public class MainViewModel : NotifyPropertyBase
    {
        public ObservableCollection<Person> _people;
        public ObservableCollection<Person> People
        {
            get { return _people; }
            set { SetProperty(ref _people, value); }
        }


        public  MainViewModel ()
        {            
            People = new ObservableCollection<Person>()
            {
                new Person { Name = "葉大雄", Address ="台北市信義路 58 號", Age=61 },
                new Person { Name = "胖虎", Address ="台中市台灣大道七段 1009 號", Age=34 },
                new Person { Name = "小夫", Address ="台北市松仁路 1 號", Age=37 },
                new Person { Name = "魯夫", Address ="高雄市七賢二路 321 號", Age=28 },
                new Person { Name = "幕之內一步", Address ="台北市忠孝東路路走九遍", Age=23 },
                new Person { Name = "索隆", Address ="台北市中山北路二段 575 號", Age=31 },
                new Person { Name = "悟空", Address ="台北市愛國東路路 1 號", Age=38 },
                new Person { Name = "香吉士", Address ="桃園市經國路 997 號", Age=21 },
            };            
        }
    }
修改 MainPage.xaml

 

<Page
    x:Class="UnoCollectionBindingSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UnoCollectionBindingSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="using:UnoCollectionBindingSample.ViewModels"
    mc:Ignorable="d">
    <Page.DataContext>
        <vm:MainViewModel/>
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="4,32,4,4">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListView ItemsSource="{Binding People}" >
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment"  Value="Stretch"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate >
                <DataTemplate >
                    <Border BorderBrush="Gold" BorderThickness="2">
                        <Border.Resources >
                            <Style TargetType="TextBlock" x:Key="textStyle">
                                <Setter Property="Margin" Value="6"/>
                                <Setter Property="FontSize" Value="13"/>
                                <Setter Property="Foreground" Value="DarkBlue" />
                            </Style>
                        </Border.Resources>
                        <Grid>
                            <Grid.RowDefinitions >
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid Grid.Row="0" >
                                <Grid.ColumnDefinitions >
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="100"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Text="{Binding Name}" Style="{StaticResource textStyle}"/>
                                <TextBlock Text="{Binding Age}" Grid.Column="1" Style="{StaticResource textStyle}"/>
                            </Grid>
                            <TextBlock Text="{Binding Address}" Grid.Row="1" Style="{StaticResource textStyle}"/>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</Page>
執行結果
Android iOS

既然都玩到這兒了,不如就順帶測試一下 Element Binding 吧。我們給 ListView 一個 x:Name 設定,接著增加一個 StackPanel (Grid.Row=1);在這繫結 ListView 的 SelectedItem,藉以顯示目前選項。

再度修改 MainPage.xaml
<Page
    x:Class="UnoCollectionBindingSample.MainPage"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:local="using:UnoCollectionBindingSample"
    xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
    xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
    xmlns:vm="using:UnoCollectionBindingSample.ViewModels"
    mc:Ignorable="d">
    <Page.DataContext>
        <vm:MainViewModel/>
    </Page.DataContext>
    <Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="4,32,4,4">
        <Grid.RowDefinitions>
            <RowDefinition Height="*"/>
            <RowDefinition Height="Auto"/>
        </Grid.RowDefinitions>
        <ListView ItemsSource="{Binding People}" x:Name="listview">
            <ListView.ItemContainerStyle>
                <Style TargetType="ListViewItem">
                    <Setter Property="HorizontalContentAlignment"  Value="Stretch"/>
                </Style>
            </ListView.ItemContainerStyle>
            <ListView.ItemTemplate >
                <DataTemplate >
                    <Border BorderBrush="Gold" BorderThickness="2">
                        <Border.Resources >
                            <Style TargetType="TextBlock" x:Key="textStyle">
                                <Setter Property="Margin" Value="6"/>
                                <Setter Property="FontSize" Value="13"/>
                                <Setter Property="Foreground" Value="DarkBlue" />
                            </Style>
                        </Border.Resources>
                        <Grid>
                            <Grid.RowDefinitions >
                                <RowDefinition Height="Auto"/>
                                <RowDefinition Height="Auto"/>
                            </Grid.RowDefinitions>
                            <Grid Grid.Row="0" >
                                <Grid.ColumnDefinitions >
                                    <ColumnDefinition Width="*"/>
                                    <ColumnDefinition Width="100"/>
                                </Grid.ColumnDefinitions>
                                <TextBlock Text="{Binding Name}" Style="{StaticResource textStyle}"/>
                                <TextBlock Text="{Binding Age}" Grid.Column="1" Style="{StaticResource textStyle}"/>
                            </Grid>
                            <TextBlock Text="{Binding Address}" Grid.Row="1" Style="{StaticResource textStyle}"/>
                        </Grid>
                    </Border>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
        <StackPanel Grid.Row="1" DataContext="{Binding ElementName=listview, Path=SelectedItem}" Margin="4,6,4,12">
            <TextBlock Text="選擇的是"/>
            <TextBlock Text="{Binding Name}"/>
        </StackPanel>
    </Grid>
</Page>

 經過測試,Element binding 能夠正常運作。這個範例的原始碼位於 https://github.com/billchungiii/UnoCollectionBindingSample

註:截至目前為止,Uno Platform 還沒有支援匿名的 Style 設定。