在上一篇博文《[UWP]使用Popup構建UWP Picker》中咱們簡單講述了一下使用Popup構建適用於MVVM框架下的彈窗層組件Picker的過程。可是沒有應用實例的話可能體現不出Picker相對於ContentDialog的優勢在哪裏,畢竟Linus大神說過:html
Talk is cheap, show me the code!git
咱們假定要實現這樣一個顏色選擇器:當用戶須要選擇一個顏色時,應用彈出顏色選擇器,用戶選擇完成後,點擊「肯定」按鈕關閉彈窗,而且向調用方代碼返回用戶選擇的顏色值。github
它的調用界面是這樣的:express
上篇博文裏咱們講到要實現Picker功能,其ViewModel必須實現IObjectPicker接口。我在HHChaosToolkit庫中已經定義了ObjectPickerBase做爲Picker的公共基類,咱們的ViewModel直接繼承它就能夠了。c#
IObjectPicker的接口定義:框架
public interface IObjectPicker<T> { event EventHandler<ObjectPickedEventArgs<T>> ObjectPicked; event EventHandler Canceled; }
ObjectPickerBase的定義:ide
public abstract class ObjectPickerBase<T> : ViewModelBase, IObjectPicker<T> { public event EventHandler<ObjectPickedEventArgs<T>> ObjectPicked; public event EventHandler Canceled; /// <summary> /// 設置選擇的對象 /// </summary> /// <param name="result"></param> public void SetResult(T result) { ObjectPicked?.Invoke(this, new ObjectPickedEventArgs<T>(result)); } /// <summary> /// 取消Pick操做 /// </summary> public void Exit() { Canceled?.Invoke(this, EventArgs.Empty); } public RelayCommand ExitCommand => new RelayCommand(Exit); }
這裏咱們編寫一個TestColorPickerViewModel做爲ColorPicker彈窗界面的ViewModel,其代碼以下:動畫
public class TestColorPickerViewModel: ObjectPickerBase<Color> { private Color _pickedColor; public Color PickedColor { get => _pickedColor; set => Set(ref _pickedColor, value); } public override void OnNavigatedTo(NavigationEventArgs e) { if (e.Parameter is Color color) { PickedColor = color; } base.OnNavigatedTo(e); } public ICommand PickColorCommand => new RelayCommand(() => { SetResult(PickedColor); }); }
其中有一個重載的方法OnNavigatedTo,這個用於接受打開彈窗時給傳遞給Picker的參數,這個屬於HHChaosToolkit類庫中MVVM導航服務的一部分功能,之後的博客我可能會拿出來單獨講一下。ui
咱們看到,TestColorPickerViewModel的代碼邏輯很是簡單,在執行PickColorCommand後返回PickedColor做爲結果。this
View層交互很少,咱們新建一個Page,而後添加一個ColorPicker控件,Color屬性綁定ViewModel的PickedColor,添加一個「肯定」按鈕綁定PickColorCommand,xaml.cs文件中無需添加任何代碼,xaml代碼以下:
<Page x:Class="HHChaosToolkit.Sample.Views.TestPages.TestColorPickerPage" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" xmlns:local="using:HHChaosToolkit.Sample.Views.TestPages" xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" DataContext="{Binding TestColorPickerViewModel, Source={StaticResource Locator}}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}"> <Grid> <Grid Background="White" BorderBrush="#d9ddea" BorderThickness="1"> <Grid.RowDefinitions> <RowDefinition Height="Auto" /> <RowDefinition /> <RowDefinition Height="Auto" /> </Grid.RowDefinitions> <Grid Height="40" Background="#d9ddea"> <Grid.ColumnDefinitions> <ColumnDefinition /> <ColumnDefinition Width="auto" /> </Grid.ColumnDefinitions> <TextBlock Margin="15,0" VerticalAlignment="Center" FontSize="14px" Foreground="#474261" Text="ColorPicker" /> <Button Grid.Column="1" Command="{Binding ExitCommand}" Style="{StaticResource PickerCloseButtonStyle}" /> </Grid> <Grid Grid.Row="1" Padding="20,10"> <ColorPicker x:Name="ColorPicker" Color="{Binding PickedColor,Mode=TwoWay}"/> </Grid> <Grid Grid.Row="2" Padding="20"> <Button HorizontalAlignment="Center" Content="肯定" Command="{Binding PickColorCommand}"/> </Grid> </Grid> </Grid> </Page>
咱們首先要在ViewModelLocator中註冊TestColorPickerViewModel爲可選取Color類型的Picker對象,代碼以下:
RegisterObjectPicker<Color, TestColorPickerViewModel, TestColorPickerPage>();
其中RegisterObjectPicker方法的源碼以下:
public void RegisterObjectPicker<T, VM, V>() where VM : ObjectPickerBase<T> { SimpleIoc.Default.Register<VM>(); ObjectPickerService.Configure(typeof(T).FullName, typeof(VM).FullName, typeof(V)); }
這段代碼目的是在ObjectPickerService中註冊TestColorPickerViewModel爲可選取Color類型的Picker對象,這樣咱們以後的調用能夠直接經過ObjectPickerService來進行。
必需要說明的是ObjectPickerService能夠爲同一類型註冊多個Picker對象,相似於Windows系統中可安裝多個視頻播放器,調用時指定使用哪一個播放器便可。
在ObjectPickerService中註冊事後,咱們便可在任意須要選取顏色的地方使用咱們的ColorPicker彈窗,最簡單的調用方法時這樣的:
var pickerService = ServiceLocator.Current.GetInstance<ObjectPickerService>(); var ret = await pickerService.PickSingleObjectAsync<Color>(typeof(TestColorPickerViewModel) .FullName, PickedColor); if (!ret.Canceled) { PickedColor = ret.Result; var toast = new Toast($"You picked a new color!({ret.Result})"); toast.Show(); }
固然咱們也能夠自定義彈出界面的位置、背景、動畫及點擊空白區域退出等選項。若是須要這樣自定義的話,咱們要用到PickerOpenOption這個類,這個類用來設置Picker彈出時的自定義配置項,例如:
var pickerService = ServiceLocator.Current.GetInstance<ObjectPickerService>(); var openOption = new PickerOpenOption { EnableTapBlackAreaExit = true, VerticalAlignment = VerticalAlignment.Stretch, HorizontalAlignment = HorizontalAlignment.Right, Background = new AcrylicBrush { TintOpacity = 0.1 }, Transitions = new TransitionCollection { new EdgeUIThemeTransition { Edge = EdgeTransitionLocation.Right } } }; var ret = await pickerService.PickSingleObjectAsync<Color>(typeof(TestColorPickerViewModel) .FullName, PickedColor, openOption); if (!ret.Canceled) { PickedColor = ret.Result; var toast = new Toast($"You picked a new color!({ret.Result})"); toast.Show(); }
它的呈現效果是這樣的:
這篇博文裏我給你們講解了如何使用Picker來構建一個顏色選擇器彈窗,這只是一個小例子,Picker有很是多的使用場景,例如:
最後,完整項目代碼連接在這裏:GitHub連接點這裏,歡迎你們使用,或者提出意見!
本篇博客到此結束!謝謝你們!