在上一篇博文《[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连接点这里,欢迎你们使用,或者提出意见!
本篇博客到此结束!谢谢你们!