WPF與DevExpress之——實現類似於安裝程序下一步下一步的樣式窗體


話不多說先上圖

 

 

 點擊下一步

 

 

 跳轉到第二頁

 

 

 項目准備:

1.DevExpress 19/18/17(三個版本都可以)

2.Vs2019

3..Net framework>4.0

項目結構:

 

 

 項目步驟:

1.導入項目所需的DLL

每個DLL的含義和作用可以去官網或者客戶端工具查看

 

 

 2.構建主界面

DevExpress的導航控件具有跳轉的功能,我們這里使用的就是DevExpress的NavigationFrame控件。

它存在DevExpress.Xpf.Controls的DevExpress.Xpf.WindowsUI命名空間下。

 

 

 我們在主界面里面裝入此控件,並且在控件內設置第一頁指向的界面。

<dx:ThemedWindow x:Class="NextDemo.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
        xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
        xmlns:dxwui="http://schemas.devexpress.com/winfx/2008/xaml/windowsui"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:NextDemo"
        mc:Ignorable="d"
        ResizeMode="CanMinimize"
        Title="騰訊QQ安裝程序" Height="450" Width="800">
    <Grid>
        <dx:LoadingDecorator>
            <dxwui:NavigationFrame x:Name="frame" Source="InstallStep1" BackNavigationMode="Root"//這里的source就是指向的界面的名字
                               AnimationType="SlideHorizontal"
                               AnimationSpeedRatio="1">
            </dxwui:NavigationFrame>
        </dx:LoadingDecorator>
    </Grid>
</dx:ThemedWindow>

那么這里的Source屬性是如何指向界面的呢?

其實它會根據名字去同一個命名空間下尋找同名的類,所以這里要確保你的界面要和主界面是一個命名空間,不然尋找失敗,DevExpress就會將之轉化為字符串進行展示

下圖中,我們在Views文件夾中創建第一頁顯示的用戶控件,並且將命名空間與主界面修改為一致

 

主界面對應后台代碼

public partial class MainWindow
    {
        public MainWindow()
        {
            InitializeComponent();
            //設置樣式
            ApplicationThemeHelper.UseLegacyDefaultTheme = true;
            ApplicationThemeHelper.ApplicationThemeName = Theme.Office2019DarkGray.Name;
            this.WindowStyle = System.Windows.WindowStyle.SingleBorderWindow;
            this.BorderThickness = new Thickness(0);
            this.Margin = new Thickness(0);
            this.Padding = new Thickness(0);
            this.Icon = new BitmapImage(new Uri("pack://application:,,,/Images/QQ.jpg"));
            //綁定模型
            var viewModel = new InstallViewModel();
            viewModel.NavigatePage += frame.Navigate;//重點:綁定導航切換方法
            this.DataContext = viewModel;
        }
    }

我們將NavigationFrame的導航切換事件綁定到我們視圖模型上面,並且這是一個總的ViewModel,為什么不在每個界面里做這種操作

1.因為NavigationFrame控件在主界面中,如果我們在每一頁都想去操作它,就得作為傳輸參數,提高了耦合

2.我們可以使每一頁的視圖模型都去繼承MainWindow的視圖模型,重寫該事件,從而可以根據具體業務定制頁面跳轉,實現多態。(demo中並沒有這樣做。hhhhh)

 3.對第一個界面進行處理,我就稍微模仿了下一些程序的安裝程序

直接上代碼

 

<UserControl x:Class="NextDemo.InstallStep1"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
             xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
             xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
             xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
             xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
             xmlns:dxmvvm="http://schemas.devexpress.com/winfx/2008/xaml/mvvm"
             xmlns:local="clr-namespace:NextDemo"
             mc:Ignorable="d" 
             d:DesignHeight="450" d:DesignWidth="800">
    <dxmvvm:Interaction.Behaviors>
        <dx:DXMessageBoxService/>
        <dx:CurrentDialogService/>
    </dxmvvm:Interaction.Behaviors>
    <Grid>
        <dxlc:LayoutControl VerticalAlignment="Stretch" Orientation="Vertical" TextBlock.FontSize="12">
            <Label VerticalAlignment="Top" FontWeight="Bold" TextBlock.FontSize="14" Content="請同意我們相關的協議" Foreground="Black"></Label>
            <dxlc:LayoutGroup Orientation="Horizontal">
                <TextBlock TextWrapping = "Wrap">歡迎您使用騰訊QQ軟件及服務</TextBlock>
            </dxlc:LayoutGroup>
            <dxlc:LayoutGroup VerticalAlignment="Bottom" Orientation="Horizontal">
                <dxlc:LayoutGroup Orientation="Vertical" HorizontalAlignment="Left">
                    <dxe:CheckEdit   Content="我同意" HorizontalAlignment="Left"/>
                    <dxe:CheckEdit   Content="我不太同意" HorizontalAlignment="Left"/>
                </dxlc:LayoutGroup>
                <dxlc:LayoutGroup  HorizontalAlignment="Right" VerticalAlignment="Bottom">
                    <dx:SimpleButton Content="下一步" Width="80" Height="20" FontWeight="Bold"  Command="{Binding NextCommand}" VerticalAlignment="Bottom"></dx:SimpleButton>
                    <dx:SimpleButton Content="取消安裝" Width="80" Height="20" Command="{Binding CancelCommand}" VerticalAlignment="Bottom"></dx:SimpleButton>
                </dxlc:LayoutGroup>
            </dxlc:LayoutGroup>
        </dxlc:LayoutControl>
        <dx:WaitIndicator  DeferedVisibility="{Binding IsLoading}" />
    </Grid>
</UserControl>

 

這里使用到了DevExpress自帶的MVVM模式,不太了解的同學可以去官網或者我的文章了解下,其實和WPF自帶的很像。

對"下一步"進行命令綁定。

WaitIndicator是WPF自帶的一個加載中控件。我將之是否顯示綁定到一個IsLoading屬性。

4.處理業務,完成VIewModel

internal Action<string> NavigatePage;

這就是步驟二中綁定的導航的跳轉事件對象

有了它我們就可以自由調用它,進行跳轉。委托參數是跳轉的視圖的名字,同樣也得是統一命名空間。

private void JumpToStepTwo()
        {
           //業務或者跳轉判斷
           //....
           //跳轉到對應的命名空間下的用戶控件
            NavigatePage?.Invoke("IntallStep2");
        }

對下一步就行命令綁定的實現

 public event Action NextAction;//跳轉下一步的事件,
private async Task Next()
        {
            IsLoading = true;
            try
            {
                await Task.Delay(2000);//模擬業務耗時

                NextAction?.Invoke();
            }
            catch(Exception ex) { throw ex; }
            finally
            {
                IsLoading = false;
            }
        }
NextCommand = new AsyncCommand(Next);

這樣下一步的功能就可以使用了,具體業務自己實現就行了。

ViewModel代碼

public class InstallViewModel:ViewModelBase
    {
        bool _loading;
        public bool IsLoading
        {
            get { return _loading; }
            set { SetProperty(ref _loading, value,nameof(IsLoading) ); }
        }
        internal Action<string> NavigatePage;
        //以下兩個建議提交到基類中定義
        public AsyncCommand NextCommand { get; set; }//下一步的命令
        public event Action NextAction;//跳轉下一步的事件,
        //業務邏輯
        public InstallViewModel()
        {
            NextCommand = new AsyncCommand(Next);
            NextAction += JumpToStepTwo;
        }
        private async Task Next()
        {
            IsLoading = true;
            try
            {
                await Task.Delay(2000);//模擬業務耗時

                NextAction?.Invoke();
            }
            catch(Exception ex) { throw ex; }
            finally
            {
                IsLoading = false;
            }
        }
        private void JumpToStepTwo()
        {
           //業務或者跳轉判斷
           //....
           //跳轉到對應的命名空間下的用戶控件
            NavigatePage?.Invoke("IntallStep2");
        }
    }

最后提一下,就是下一步,上一步,取消,都應該提到一個基類視圖模型中,然后繼承,自己根據業務實現特定的功能。

代碼已經上傳GitHub

覺得有用的話給個星星吧ballball你們!!!

 

 


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM