[UWP]使用Picker实现一个简单的ColorPicker弹窗

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

Talk is cheap, show me the code!

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

它的调用界面是这样的:

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

上篇博文里我们讲到要实现Picker功能,其ViewModel必须实现IObjectPicker

IObjectPicker

public interface IObjectPicker<T>
{
    event EventHandler<ObjectPickedEventArgs<T>> ObjectPicked;
    event EventHandler Canceled;
}

ObjectPickerBase

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导航服务的一部分功能,以后的博客我可能会拿出来单独讲一下。

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

编写ColorPicker的UI层代码

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>

注册调用过程

注册ColorPicker弹窗

我们首先要在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系统中可安装多个视频播放器,调用时指定使用哪个播放器即可。

调用ColorPicker弹窗

在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有非常多的使用场景,例如:

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

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

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

原文地址:https://www.cnblogs.com/hhchaos/p/9961258.html

时间: 2024-10-25 12:07:52

[UWP]使用Picker实现一个简单的ColorPicker弹窗的相关文章

一个简单的页面弹窗插件 jquery.pageMsgFrame.js

页面弹窗是网站中常用的交互效果,它可以强提示网站的某些信息给用户,或者作用于某些信息的修改等等功能. 这几天在做一个项目的时候,就顺捎把这个插件写一下,栽棵树,自己乘凉吧. 原创博文,转载请注明出处:http://www.cnblogs.com/dereksunok/p/3724764.html html代码: 1 <!doctype html> 2 <html> 3 <head> 4 <meta charset="utf-8" /> 5

iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 - 文顶顶

原文  http://www.cnblogs.com/wendingding/p/3771047.html iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 一.实现效果 说明: 点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162,不可修改. 2.显示数据,需要设置数据源,也有两种方式(成为数据源,遵守协议) 3.实现数据源里面的两个方法 1)返回一共有多少列 2)在这一列中一共有多少行 4.通过代理告诉它那一列的哪

使用picker View控件完成一个简单的选餐应用

使用picker View控件完成一个简单的选餐应用 一.实现效果 说明:点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162,不可修改. 2.显示数据,需要设置数据源,也有两种方式(成为数据源,遵守协议) 3.实现数据源里面的两个方法 1)返回一共有多少列 2)在这一列中一共有多少行 4.通过代理告诉它那一列的哪一行显示哪些数据(设置其代理为控制器) 5.使用懒加载,加载所有的食物 6.完成基本数据的展示(列,行,内容) 7.自动更新选中

iOS基础-选择空间Picker View的简单使用

iOS开发UI篇—使用picker View控件完成一个简单的选餐应用 一.实现效果 说明:点击随机按钮,能够自动选取,下方数据自动刷新. 二.实现思路 1.picker view的有默认高度为162,不可修改. 2.显示数据,需要设置数据源,也有两种方式(成为数据源,遵守协议) 3.实现数据源里面的两个方法 1)返回一共有多少列 2)在这一列中一共有多少行 4.通过代理告诉它那一列的哪一行显示哪些数据(设置其代理为控制器) 5.使用懒加载,加载所有的食物 6.完成基本数据的展示(列,行,内容)

可视化程序设计基础(三)——一个简单的播放器(并不)

本次的作业是制作一个简单的播放器,功能仅限于播放视频和音频,虽说是简单的播放器,但其中还是有很多细节需要注意的. 问题一:布局 本来这个问题不应该是一个问题了,之前老师讲过的Stackpanel和Grid等对于布局一个播放器来说绰绰有余,但上次上课老师提到的NavigationView令我十分感兴趣,这是一个uwp应用程序中随处可见的一种布局,节省了开发者很多的时间. 所以我就着手于建立这个NavigationView了,首先我看了一下XAML Controls Gallery,然而其中关于Na

一个简单的主机管理模拟程序

最近写的一个小练习,主要是把前面学的东西整合一下.写了一个简单的主机管理界面,主要是练习以下知识点: Session和Cookie进行登录验证(装饰器) 数据库的基本操作 (单表,1对多,多对多) Form的简单使用实现验证 Bootstrap模板写个简单界面 自定义分页 信号,中间件,CSRF,模板语言,JavaScript,AJAX等等 界面比较low,毕竟不是专业的. 附件里面是Django的源代码,3个文件放在一起winrar解压就可以打开

Windows 上静态编译 Libevent 2.0.10 并实现一个简单 HTTP 服务器(无数截图)

[文章作者:张宴 本文版本:v1.0 最后修改:2011.03.30 转载请注明原文链接:http://blog.s135.com/libevent_windows/] 本文介绍了如何在 Windows 操作系统中,利用微软 Visual Studio 2005 编译生成 Libevent 2.0.10 静态链接库,并利用 Libevent 静态链接库,实现一个简单的 HTTP Web服务器程序:httpd.exe. 假设 Visual Studio 2005 的安装路径为“D:\Program

完成一个简单的时间片轮转多道程序内核代码

王康 + 原创作品转载请注明出处 + <Linux内核分析>MOOC课程http://mooc.study.163.com/course/USTC-1000029000 " 分别是1 存储程序计算机工作模型,cpu执行程序的基础流程: 2 函数调用堆栈:各种寄存器和存储主要是为了指令的传取值,通过eip,esp,eax,ebp和程序内存的分区,搭配push pop call return leave等一系列指令完成函数调用操作. 3 中断:多道批程序! 在复习一下上一讲的几个重要指令

一个简单的税利计算器(网页版)

嗯嗯,做一个简单的网页版的税率计算器,功能比较简单,但是相对比较实用.因为参考了一些其他作品,所以在计算汇率的时候习惯性的是以美元做单位.具体的功能有着较为详细的标注.仅供大家学习参考下. <!DOCTYPE html> <html> <head lang="en"> <meta charset="UTF-8"> <title>JavaScript Loan Calculator</title>