[UWP]使用Picker實現一個簡單的ColorPicker彈窗

在上一篇博文《[UWP]使用Popup構建UWP Picker》中咱們簡單講述了一下使用Popup構建適用於MVVM框架下的彈窗層組件Picker的過程。可是沒有應用實例的話可能體現不出Picker相對於ContentDialog的優勢在哪裏,畢竟Linus大神說過:html

Talk is cheap, show me the code!git

咱們假定要實現這樣一個顏色選擇器:當用戶須要選擇一個顏色時,應用彈出顏色選擇器,用戶選擇完成後,點擊「肯定」按鈕關閉彈窗,而且向調用方代碼返回用戶選擇的顏色值。github

它的調用界面是這樣的:express

ColorPicker

編寫ColorPicker彈窗的業務邏輯代碼

上篇博文裏咱們講到要實現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

編寫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();
        }

它的呈現效果是這樣的:

ColorPicker

結尾

這篇博文裏我給你們講解了如何使用Picker來構建一個顏色選擇器彈窗,這只是一個小例子,Picker有很是多的使用場景,例如:

  • 文本輸入彈窗(註冊類型爲string);
  • 普通自定義Dialog界面(統一註冊類型爲bool便可);
  • 圖片編輯彈窗(註冊類型爲文件或者圖片);
  • ...

最後,完整項目代碼連接在這裏:GitHub連接點這裏,歡迎你們使用,或者提出意見!

本篇博客到此結束!謝謝你們!

相關文章
相關標籤/搜索