经验首页 前端设计 程序设计 Java相关 移动开发 数据库/运维 软件/图像 大数据/云计算 其他经验
当前位置:技术经验 » 程序设计 » ASP.net » 查看文章
[UWP]使用Picker实现一个简单的ColorPicker弹窗
来源:cnblogs  作者:HHChaos  时间:2018/11/16 10:27:04  对本文有异议

在上一篇博文《[UWP]使用Popup构建UWP Picker》中我们简单讲述了一下使用Popup构建适用于MVVM框架下的弹窗层组件Picker的过程。但是没有应用实例的话可能体现不出Picker相对于ContentDialog的优点在哪里,毕竟Linus大神说过:

Talk is cheap, show me the code!

我们假定要实现这样一个颜色选择器:当用户需要选择一个颜色时,应用弹出颜色选择器,用户选择完成后,点击“确定”按钮关闭弹窗,并且向调用方代码返回用户选择的颜色值。

它的调用界面是这样的:

ColorPicker

编写ColorPicker弹窗的业务逻辑代码

上篇博文里我们讲到要实现Picker功能,其ViewModel必须实现IObjectPicker接口。我在HHChaosToolkit库中已经定义了ObjectPickerBase作为Picker的公共基类,我们的ViewModel直接继承它就可以了。

IObjectPicker的接口定义:

  1. public interface IObjectPicker<T>
  2. {
  3. event EventHandler<ObjectPickedEventArgs<T>> ObjectPicked;
  4. event EventHandler Canceled;
  5. }

ObjectPickerBase的定义:

  1. public abstract class ObjectPickerBase<T> : ViewModelBase, IObjectPicker<T>
  2. {
  3. public event EventHandler<ObjectPickedEventArgs<T>> ObjectPicked;
  4. public event EventHandler Canceled;
  5. /// <summary>
  6. /// 设置选择的对象
  7. /// </summary>
  8. /// <param name="result"></param>
  9. public void SetResult(T result)
  10. {
  11. ObjectPicked?.Invoke(this, new ObjectPickedEventArgs<T>(result));
  12. }
  13. /// <summary>
  14. /// 取消Pick操作
  15. /// </summary>
  16. public void Exit()
  17. {
  18. Canceled?.Invoke(this, EventArgs.Empty);
  19. }
  20. public RelayCommand ExitCommand => new RelayCommand(Exit);
  21. }

这里我们编写一个TestColorPickerViewModel作为ColorPicker弹窗界面的ViewModel,其代码如下:

  1. public class TestColorPickerViewModel: ObjectPickerBase<Color>
  2. {
  3. private Color _pickedColor;
  4. public Color PickedColor
  5. {
  6. get => _pickedColor;
  7. set => Set(ref _pickedColor, value);
  8. }
  9. public override void OnNavigatedTo(NavigationEventArgs e)
  10. {
  11. if (e.Parameter is Color color)
  12. {
  13. PickedColor = color;
  14. }
  15. base.OnNavigatedTo(e);
  16. }
  17. public ICommand PickColorCommand => new RelayCommand(() =>
  18. {
  19. SetResult(PickedColor);
  20. });
  21. }

其中有一个重载的方法OnNavigatedTo,这个用于接受打开弹窗时给传递给Picker的参数,这个属于HHChaosToolkit类库中MVVM导航服务的一部分功能,以后的博客我可能会拿出来单独讲一下。

我们看到,TestColorPickerViewModel的代码逻辑非常简单,在执行PickColorCommand后返回PickedColor作为结果。

编写ColorPicker的UI层代码

View层交互不多,我们新建一个Page,然后添加一个ColorPicker控件,Color属性绑定ViewModel的PickedColor,添加一个“确定”按钮绑定PickColorCommand,xaml.cs文件中无需添加任何代码,xaml代码如下:

  1. <Page
  2. x:Class="HHChaosToolkit.Sample.Views.TestPages.TestColorPickerPage"
  3. xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  4. xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  5. xmlns:local="using:HHChaosToolkit.Sample.Views.TestPages"
  6. xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
  7. xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
  8. mc:Ignorable="d"
  9. DataContext="{Binding TestColorPickerViewModel, Source={StaticResource Locator}}"
  10. Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
  11. <Grid>
  12. <Grid Background="White" BorderBrush="#d9ddea" BorderThickness="1">
  13. <Grid.RowDefinitions>
  14. <RowDefinition Height="Auto" />
  15. <RowDefinition />
  16. <RowDefinition Height="Auto" />
  17. </Grid.RowDefinitions>
  18. <Grid Height="40" Background="#d9ddea">
  19. <Grid.ColumnDefinitions>
  20. <ColumnDefinition />
  21. <ColumnDefinition Width="auto" />
  22. </Grid.ColumnDefinitions>
  23. <TextBlock
  24. Margin="15,0"
  25. VerticalAlignment="Center"
  26. FontSize="14px"
  27. Foreground="#474261"
  28. Text="ColorPicker" />
  29. <Button
  30. Grid.Column="1"
  31. Command="{Binding ExitCommand}"
  32. Style="{StaticResource PickerCloseButtonStyle}" />
  33. </Grid>
  34. <Grid Grid.Row="1" Padding="20,10">
  35. <ColorPicker x:Name="ColorPicker" Color="{Binding PickedColor,Mode=TwoWay}"/>
  36. </Grid>
  37. <Grid Grid.Row="2" Padding="20">
  38. <Button HorizontalAlignment="Center" Content="确定" Command="{Binding PickColorCommand}"/>
  39. </Grid>
  40. </Grid>
  41. </Grid>
  42. </Page>

注册调用过程

注册ColorPicker弹窗

我们首先要在ViewModelLocator中注册TestColorPickerViewModel为可选取Color类型的Picker对象,代码如下:

  1. RegisterObjectPicker<Color, TestColorPickerViewModel, TestColorPickerPage>();

其中RegisterObjectPicker方法的源码如下:

  1. public void RegisterObjectPicker<T, VM, V>()
  2. where VM : ObjectPickerBase<T>
  3. {
  4. SimpleIoc.Default.Register<VM>();
  5. ObjectPickerService.Configure(typeof(T).FullName, typeof(VM).FullName, typeof(V));
  6. }

这段代码目的是在ObjectPickerService中注册TestColorPickerViewModel为可选取Color类型的Picker对象,这样我们之后的调用可以直接通过ObjectPickerService来进行。

必须要说明的是ObjectPickerService可以为同一类型注册多个Picker对象,类似于Windows系统中可安装多个视频播放器,调用时指定使用哪个播放器即可。

调用ColorPicker弹窗

在ObjectPickerService中注册过后,我们即可在任意需要选取颜色的地方使用我们的ColorPicker弹窗,最简单的调用方法时这样的:

  1. var pickerService = ServiceLocator.Current.GetInstance<ObjectPickerService>();
  2. var ret = await pickerService.PickSingleObjectAsync<Color>(typeof(TestColorPickerViewModel)
  3. .FullName, PickedColor);
  4. if (!ret.Canceled)
  5. {
  6. PickedColor = ret.Result;
  7. var toast = new Toast($"You picked a new color!({ret.Result})");
  8. toast.Show();
  9. }

当然我们也可以自定义弹出界面的位置、背景、动画及点击空白区域退出等选项。如果需要这样自定义的话,我们要用到PickerOpenOption这个类,这个类用来设置Picker弹出时的自定义配置项,例如:

  1. var pickerService = ServiceLocator.Current.GetInstance<ObjectPickerService>();
  2. var openOption = new PickerOpenOption
  3. {
  4. EnableTapBlackAreaExit = true,
  5. VerticalAlignment = VerticalAlignment.Stretch,
  6. HorizontalAlignment = HorizontalAlignment.Right,
  7. Background = new AcrylicBrush
  8. {
  9. TintOpacity = 0.1
  10. },
  11. Transitions = new TransitionCollection
  12. {
  13. new EdgeUIThemeTransition
  14. {
  15. Edge = EdgeTransitionLocation.Right
  16. }
  17. }
  18. };
  19. var ret = await pickerService.PickSingleObjectAsync<Color>(typeof(TestColorPickerViewModel)
  20. .FullName, PickedColor, openOption);
  21. if (!ret.Canceled)
  22. {
  23. PickedColor = ret.Result;
  24. var toast = new Toast($"You picked a new color!({ret.Result})");
  25. toast.Show();
  26. }

它的呈现效果是这样的:

ColorPicker

结尾

这篇博文里我给大家讲解了如何使用Picker来构建一个颜色选择器弹窗,这只是一个小例子,Picker有非常多的使用场景,例如:

  • 文本输入弹窗(注册类型为string);
  • 普通自定义Dialog界面(统一注册类型为bool即可);
  • 图片编辑弹窗(注册类型为文件或者图片);
  • ...

最后,完整项目代码链接在这里:GitHub链接点这里,欢迎大家使用,或者提出意见!

本篇博客到此结束!谢谢大家!

 友情链接:直通硅谷  点职佳  北美留学生论坛

本站QQ群:前端 618073944 | Java 606181507 | Python 626812652 | C/C++ 612253063 | 微信 634508462 | 苹果 692586424 | C#/.net 182808419 | PHP 305140648 | 运维 608723728

W3xue 的所有内容仅供测试,对任何法律问题及风险不承担任何责任。通过使用本站内容随之而来的风险与本站无关。
关于我们  |  意见建议  |  捐助我们  |  报错有奖  |  广告合作、友情链接(目前9元/月)请联系QQ:27243702 沸活量
皖ICP备17017327号-2 皖公网安备34020702000426号