資料和命令繫結是各種 xaml 平台裡非常重要的一項特色,這場偵查就寫個體脂肪計算器測試看看。
Uno.UI version: 1.40.0 穩定版
偵查對象:Data and Command Binding
偵查對象:Data and Command Binding
資料和命令繫結向來是使用 xaml 的各式平台的重頭大戲,這一篇我們同時來測試簡單的資料和命令繫結。程式本身內容很簡單,就是個 BMI 的計算器而已。
簡易的命令通用類別,RelayCommand class
public class RelayCommand : ICommand
{
private readonly Action<object> _executeHandler;
private readonly Func<object, bool> _canExecuteHandler;
public event EventHandler CanExecuteChanged;
public RelayCommand(Action<object> executeHandler, Func<object, bool> canExecuteHandler)
{
_executeHandler = executeHandler ?? throw new ArgumentNullException("execute handler can not be null");
_canExecuteHandler = canExecuteHandler ?? throw new ArgumentNullException("canExecute handler can not be null");
}
public RelayCommand(Action<object> execute) : this(execute, (x) => true)
{ }
public bool CanExecute(object parameter)
{
return _canExecuteHandler(parameter);
}
public void Execute(object parameter)
{
_executeHandler(parameter);
}
}
資料類別 Person class
public class Person : INotifyPropertyChanged
{
public event PropertyChangedEventHandler PropertyChanged;
private double _height;
public double Height
{
get { return _height; }
set
{
if (value != _height )
{
_height = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Height)));
}
}
}
private double _weight;
public double Weight
{
get { return _weight; }
set
{
if (value != _weight)
{
_weight = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Weight)));
}
}
}
private double _result;
public double Result
{
get { return _result; }
set
{
if (value != _result)
{
_result = value;
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(nameof(Result)));
}
}
}
private ICommand _clickCommand;
public ICommand ClickCommand
{
get
{
if (_clickCommand == null)
{
_clickCommand = new RelayCommand((x) =>
{
Result = Weight / Math.Pow(Height, 2);
});
}
return _clickCommand;
}
}
}
XAML Code
<Page
x:Class="UnoBMIApp.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UnoBMIApp"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:vm="using:UnoBMIApp.ViewModels"
mc:Ignorable="d">
<Page.DataContext>
<vm:Person/>
</Page.DataContext>
<Grid Background="{ThemeResource ApplicationPageBackgroundThemeBrush}" Margin="6,32,6,6">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<TextBlock Text="Height (M)" Grid.Row="0" Grid.Column="0" Margin="6"/>
<TextBox Text="{Binding Height, Mode=TwoWay}" Grid.Row="0" Grid.Column="1" Margin="6"/>
<TextBlock Text="Weight (Kg)" Grid.Row="1" Grid.Column="0" Margin="6"/>
<TextBox Text="{Binding Weight, Mode=TwoWay}" Grid.Row="1" Grid.Column="1" Margin="6"/>
<Button Content="Compute BMI" Command="{Binding ClickCommand}" Grid.Row="2" Grid.ColumnSpan="2" Margin="6" HorizontalAlignment="Stretch"/>
<TextBlock Text="{Binding Result, Mode=OneWay}" Grid.Row="3" Grid.ColumnSpan="2" Margin="6" HorizontalAlignment="Stretch"/>
</Grid>
</Page>
就這個範例而言,不論 Android 或 iOS 都可以正常運作。這表示 Uno Platform 基本上在簡單資料與命令繫結上是正常的,即便 Two way binding 也是如預期的反應畫面的資料變更到 view model 中。
這篇文的範例在 https://github.com/billchungiii/UnoBMIApp