“一仔播放器” WPF 的开源项目 (七 软件设置,Newtonsoft、AutoMapper、Messenger.Default.Send)
这篇主要解决宝妈不用到配置文件去改视频存放路径的问题,而是改成界面的方式。而我是打算使用Json格式,保存配置的数据。那么需要做的是主界面需要一个入口,弹入设置界面。由于需要在标题栏是加按钮,只能自定义了,不过WPF似乎有瑕疵,自定义了以后时不时的出现白边。Margin="0"Title="一仔播放器" Height="768" Width="1366" StateChanged="Window_
章节前言
这篇主要解决宝妈不用到配置文件去改视频存放路径的问题,而是改成界面的方式。而我是打算使用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;
}
}
魔乐社区(Modelers.cn) 是一个中立、公益的人工智能社区,提供人工智能工具、模型、数据的托管、展示与应用协同服务,为人工智能开发及爱好者搭建开放的学习交流平台。社区通过理事会方式运作,由全产业链共同建设、共同运营、共同享有,推动国产AI生态繁荣发展。
更多推荐




所有评论(0)