“一仔播放器” WPF 的开源项目 (七 软件设置,Newtonsoft、AutoMapper、Messenger.Default.Send)

章节前言

        这篇主要解决宝妈不用到配置文件去改视频存放路径的问题,而是改成界面的方式。而我是打算使用Json格式,保存配置的数据。那么需要做的是主界面需要一个入口,弹入设置界面。

主界面自定义

        由于需要在标题栏是加按钮,只能自定义了,不过WPF似乎有瑕疵,自定义了以后时不时的出现白边。

<hc:Window x:Class="YiZaiPlayer.View.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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:hc="https://handyorg.github.io/handycontrol" 
        xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"           
        DataContext="{Binding Source={StaticResource Locator},Path=Main}"
        Padding="0"
        Margin="0"
        WindowStyle="None"
        AllowsTransparency="True"
        WindowState="Maximized" 
        WindowStartupLocation="CenterScreen"
        Icon="/Resource/logo_32.ico"        
        mc:Ignorable="d"     
        Title="一仔播放器" Height="768" Width="1366" StateChanged="Window_StateChanged" Loaded="Window_Loaded" >
    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="29"></WindowChrome>
    </WindowChrome.WindowChrome>
    <i:Interaction.Triggers>
        <i:EventTrigger EventName="Loaded">
            <i:InvokeCommandAction Command="{Binding LoadDataCommand}"  />
        </i:EventTrigger>
    </i:Interaction.Triggers>

    <Border  BorderThickness="0">

        <Grid Margin="0,0,0,0" x:Name="grdMain">
            <Grid.RowDefinitions>
                <RowDefinition Height="29"></RowDefinition>
                <RowDefinition></RowDefinition>
            </Grid.RowDefinitions>

            <Grid.Background>
                <ImageBrush ImageSource="/Resource/cloud.png" TileMode="Tile" Opacity="0.1" Viewport="0,0,157,157" ViewportUnits="Absolute" ></ImageBrush>
            </Grid.Background>

            <Grid Grid.Row="0" Margin="0,0,0,0" Background="White" >
                <Grid.ColumnDefinitions>
                    <ColumnDefinition></ColumnDefinition>
                    <ColumnDefinition></ColumnDefinition>
                </Grid.ColumnDefinitions>

                <StackPanel Grid.Column="0" Orientation="Horizontal" HorizontalAlignment="Left" Margin="10,0,0,0">

                    <Image Source="/Resource/logo_32.ico" Width="16" Height="16"  />
                    <Label Content="{Binding AppConfig.AppName}" BorderBrush="White"></Label>

                </StackPanel>

                <StackPanel Grid.Column="1" Orientation="Horizontal" HorizontalAlignment="Right" Margin="0,0,0,0">

                    <Menu Margin="0,0,0,0" Background="Transparent"  WindowChrome.IsHitTestVisibleInChrome="True">
                        <MenuItem Height="29" Header="设置" >
                            <MenuItem Command="{Binding OpenSetWindowCommand}"  Header="基本配置">
                                <MenuItem.Icon>
                                    <Path Data="" Fill="{DynamicResource PrimaryTextBrush}" Stretch="Uniform"/>
                                </MenuItem.Icon>
                            </MenuItem>
                            <MenuItem  Header="关于软件">
                                <MenuItem.Icon>
                                    <Path Data="" Fill="{DynamicResource PrimaryTextBrush}" Stretch="Uniform"/>
                                </MenuItem.Icon>
                            </MenuItem>
                        </MenuItem>
                    </Menu>

                    <Button Click="WindowMin_Click"  hc:IconElement.Geometry="{StaticResource WindowMinGeometry}" WindowChrome.IsHitTestVisibleInChrome="True" BorderBrush="White"></Button>
                    <Button Click="WindowMax_Click" hc:IconElement.Geometry="{StaticResource WindowMaxGeometry}"  WindowChrome.IsHitTestVisibleInChrome="True" BorderBrush="White" Name="btnMax"></Button>
                    <Button Click="WindowMax_Click" hc:IconElement.Geometry="{StaticResource WindowRestoreGeometry}"  WindowChrome.IsHitTestVisibleInChrome="True" Visibility="Collapsed" BorderBrush="White" Name="btnNormal"></Button>
                    <Button Click="WindowClose_Click" hc:IconElement.Geometry="{StaticResource CloseGeometry}"  WindowChrome.IsHitTestVisibleInChrome="True"  BorderBrush="White"></Button>

                </StackPanel>

            </Grid>
            <Border Grid.Row="1" Margin="32" Padding="0,15" Background="White" >
                <Grid >
                </Grid>
            </Border>
        </Grid>
    </Border>
</hc:Window>

关键点

自定义后,顶部我们习惯了可拖拽,那还需要加上这句,但加了之后,会导致 关闭、最大化、设置等按钮,点不到,所以需要在这些控件属性,加是穿透 WindowChrome.IsHitTestVisibleInChrome="True" 

    <WindowChrome.WindowChrome>
        <WindowChrome CaptionHeight="29"></WindowChrome>
    </WindowChrome.WindowChrome>

设置界面

        按部就班,直接上代码

<Window x:Class="YiZaiPlayer.View.SetWindow"
        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:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:YiZaiPlayer.View"
        DataContext="{Binding Source={StaticResource Locator},Path=Set}"
        mc:Ignorable="d"
        ResizeMode="NoResize"
        WindowStartupLocation="CenterScreen"
        Title="设置" Height="350" Width="600">
    <Window.Resources>
        <Style TargetType="TextBlock" x:Key="tbTitle">
            <Setter Property="VerticalAlignment" Value="Center"></Setter>
            <Setter Property="HorizontalAlignment" Value="Right"></Setter>
        </Style>
    </Window.Resources>
    
    <Grid Height="250">
        <Grid.RowDefinitions>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
            <RowDefinition></RowDefinition>
        </Grid.RowDefinitions>

        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="150"></ColumnDefinition>
            <ColumnDefinition Width="300"></ColumnDefinition>
            <ColumnDefinition></ColumnDefinition>
        </Grid.ColumnDefinitions>

        <TextBlock Text="应用标题:" Grid.Row="0" Grid.Column="0" Style="{DynamicResource tbTitle}" ></TextBlock>
        <TextBlock Text="视频文件存放路径:" Grid.Row="1" Grid.Column="0"  Style="{DynamicResource tbTitle}"></TextBlock>        
        <TextBlock Text="播放器安装路径:" Grid.Row="2" Grid.Column="0"  Style="{DynamicResource tbTitle}"></TextBlock>        
        <TextBlock Text="开机启动:" Grid.Row="3" Grid.Column="0"  Style="{DynamicResource tbTitle}"></TextBlock>

        <TextBox Grid.Row="0" Grid.Column="1" Text="{Binding Config.AppName}" Height="25"></TextBox>
        <TextBox Grid.Row="1" Grid.Column="1" Text="{Binding Config.FolderPath}" Height="25"></TextBox>
        <Button  Grid.Row="1" Grid.Column="2" Content="选择" Command="{Binding OpenFolderCommand}" CommandParameter="FolderPath" HorizontalAlignment="Left" Margin="2,0,0,0"></Button>
        <TextBox Grid.Row="2" Grid.Column="1" Text="{Binding Config.PlayerPath}" Height="25"></TextBox>
        <Button  Grid.Row="2" Grid.Column="2" Content="选择" Command="{Binding OpenFolderCommand}" CommandParameter="PlayerPath"  HorizontalAlignment="Left" Margin="2,0,0,0"></Button>
        <CheckBox Grid.Row="3" Grid.Column="1" IsChecked="{Binding Config.IsAutoStart}"  ></CheckBox>

        <Button Grid.Row="4" Grid.Column="1" Content="保存" Width="100" Command="{Binding SaveConfigurationCommand}" CommandParameter="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Window}}}" HorizontalAlignment="Left"></Button>
    </Grid>
</Window>
WPF文件夹选择窗
//播放器选择
System.Windows.Forms.OpenFileDialog openFileDialog = new System.Windows.Forms.OpenFileDialog();
openFileDialog.Filter = "可执行文件(*.exe)|*.exe";
openFileDialog.FilterIndex = 1;
openFileDialog.RestoreDirectory = true;
openFileDialog.Title = "选择播放器";
openFileDialog.Multiselect = false;//选择单个
if (openFileDialog.ShowDialog() == DialogResult.OK)
{
    Config.PlayerPath = openFileDialog.FileName;
}
WPF文件选择窗
//文件夹选择
FolderBrowserDialog folderBrowserDialog = new FolderBrowserDialog();
folderBrowserDialog.SelectedPath = Config.FolderPath;    //设置初始目录

if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
{
    Config.FolderPath = folderBrowserDialog.SelectedPath;    //获取选择的文件夹的全路径名                            
}
Newtonsoft.Json

        这组件并非只是字符串转对象那么简单的基本功能,它有很多高级用法,可以设置打印格式、某些对象是否打印等等

        这是就不贴代码了,可以看看其他博主写的        

       C# Newtonsoft.Json 高级用法_李袁明的博客-CSDN博客

AutoMapper

        简单的说帮助我们完成对象间的赋值,特别是实体对象类似相同属性又一堆的情况下,需要写一堆的  modelA.id =  modelB.id.......,有了他们能省不少事,同样它的高级用法很多

        AutoMapper 快速上手 和Autofac一起用 - AutoMapper - .NET果糖网

MwvmLight.Messenger

        这是在WPF中不得不用到消息穿梭器,怎么说呢,在我们这例子中,如果我在软件设置界面点了保存,需要通知主界面重新加载就用到它了,当然他可以用在任何地方。

主界面注册信息接收的标识

Messenger.Default.Register

public MainViewModel()
{
    VideoList = new ObservableCollection<CardModel>();

    AppConfig = Common.CacheData.AppConfig;

    // 通知变更
    Messenger.Default.Register<string>(this, "MainView", (o) =>
    {
        LoadData();
    });
}
设置界面按标识发送通知

Messenger.Default.Send

/// <summary>
/// 重新配置文件
/// </summary>
public RelayCommand<System.Windows.Window> SaveConfigurationCommand
{
    get
    {
        var command = new RelayCommand<System.Windows.Window>((System.Windows.Window win) =>
        {
            // https://www.donet5.com/Doc/12/2274
            var configuration = new MapperConfiguration(cfg =>
            {
                cfg.CreateMap<ViewModel.AppConfigUI, Model.AppConfigModel>();
            });

            var mapper = configuration.CreateMapper();

            CacheData.AppConfig = mapper.Map<Model.AppConfigModel>(Config);

            //保存配置文件
            Common.CacheData.SaveConfig();

            //生成桌面图标
            new Common.QuickIcon(Common.CacheData.AppConfig.AppName).SetIcon(true, Common.CacheData.AppConfig.IsAutoStart);

            //通知变更
            Messenger.Default.Send("", "MainView");

            win.Close();

        });

        return command;
    }
}

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值