update
This commit is contained in:
parent
c6a1692f90
commit
dd2827dc71
4
App.xaml
4
App.xaml
@ -2,14 +2,16 @@
|
||||
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
|
||||
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
|
||||
xmlns:local="clr-namespace:VideoConcat"
|
||||
xmlns:conv="clr-namespace:VideoConcat.Conversions"
|
||||
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers" xmlns:local1="clr-namespace:VideoConcat.Views"
|
||||
StartupUri="Views/MainWindow.xaml">
|
||||
StartupUri="Views/LoginWindow.xaml">
|
||||
<Application.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/WPFDevelopers;component/Themes/Light.Blue.xaml"/>
|
||||
<!--需要注意 wd:Resources 必须在配色主题后,Theme="Dark" 为黑色皮肤-->
|
||||
<wd:Resources Theme="Light"/>
|
||||
|
||||
<ResourceDictionary Source="pack://application:,,,/WPFDevelopers;component/Themes/Theme.xaml"/>
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
|
||||
@ -1,4 +1,5 @@
|
||||
|
||||
using System.Net;
|
||||
using VideoConcat.Common.Tools;
|
||||
|
||||
namespace VideoConcat.Common.Api.Base
|
||||
@ -7,8 +8,25 @@ namespace VideoConcat.Common.Api.Base
|
||||
{
|
||||
public static async Task<ApiResponse<UserLoginResponse>> LoginAsync<UserLoginResponse>(string username, string password)
|
||||
{
|
||||
|
||||
string pcMachineName = Environment.MachineName;
|
||||
string pcUserName = Environment.UserName;
|
||||
|
||||
string name = Dns.GetHostName();
|
||||
string ipadrlist = Dns.GetHostAddresses(name)?.ToString()??"";
|
||||
|
||||
HttpHelper Http = new();
|
||||
ApiResponse<UserLoginResponse> res = await Http.PostAsync<UserLoginResponse>("/api/base/login", new { Username = username, Password = password, Platform = "pc" });
|
||||
ApiResponse<UserLoginResponse> res = await Http.PostAsync<UserLoginResponse>("/api/base/login",
|
||||
new
|
||||
{
|
||||
Username = username,
|
||||
Password = password,
|
||||
Platform = "pc",
|
||||
PcName = pcMachineName,
|
||||
PcUserName = pcUserName,
|
||||
Ips = ipadrlist
|
||||
}
|
||||
);
|
||||
|
||||
return res;
|
||||
}
|
||||
|
||||
@ -6,7 +6,7 @@ using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VideoConcat
|
||||
namespace VideoConcat.Conversions
|
||||
{
|
||||
public class EnumToBooleanConverter : IValueConverter
|
||||
{
|
||||
146
Models/ExtractWindowModel.cs
Normal file
146
Models/ExtractWindowModel.cs
Normal file
@ -0,0 +1,146 @@
|
||||
using Standard;
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Collections.ObjectModel;
|
||||
using System.Collections.Specialized;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.IO;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Threading;
|
||||
using System.Xml.Linq;
|
||||
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Header;
|
||||
using static VideoConcat.Models.VideoModel;
|
||||
|
||||
namespace VideoConcat.Models
|
||||
{
|
||||
|
||||
|
||||
public class ExtractWindowModel : INotifyPropertyChanged
|
||||
{
|
||||
|
||||
private string _folderPath = "";
|
||||
private string _helpInfo = "";
|
||||
private bool _canStart = false;
|
||||
private bool _isCanOperate = false;
|
||||
private bool _isStart = false;
|
||||
private string[] _videos = [];
|
||||
private Dispatcher _dispatcher;
|
||||
|
||||
public string[] videos
|
||||
{
|
||||
get => _videos;
|
||||
set
|
||||
{
|
||||
_videos = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsCanOperate
|
||||
{
|
||||
get => _isCanOperate;
|
||||
set
|
||||
{
|
||||
_isCanOperate = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool IsStart
|
||||
{
|
||||
get => _isStart;
|
||||
set
|
||||
{
|
||||
_isStart = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public Dispatcher Dispatcher
|
||||
{
|
||||
get => _dispatcher;
|
||||
set
|
||||
{
|
||||
_dispatcher = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
public class VideoStruct
|
||||
{
|
||||
public int Index { set; get; }
|
||||
public string FileName { set; get; } = "";
|
||||
public string Size { set; get; } = "";
|
||||
public int Seconds { set; get; }
|
||||
public string Status { set; get; } = "";
|
||||
public string Progress { set; get; } = "";
|
||||
}
|
||||
|
||||
public string FolderPath
|
||||
{
|
||||
get { return _folderPath; }
|
||||
set
|
||||
{
|
||||
_folderPath = value;
|
||||
OnPropertyChanged(nameof(FolderPath));
|
||||
}
|
||||
}
|
||||
|
||||
public string HelpInfo
|
||||
{
|
||||
get { return _helpInfo; }
|
||||
set
|
||||
{
|
||||
_helpInfo = value;
|
||||
OnPropertyChanged();
|
||||
}
|
||||
}
|
||||
|
||||
public bool CanStart
|
||||
{
|
||||
get { return _canStart; }
|
||||
set
|
||||
{
|
||||
_canStart = value;
|
||||
OnPropertyChanged(nameof(CanStart));
|
||||
}
|
||||
}
|
||||
|
||||
public ICommand? BtnOpenFolderCommand { get; set; }
|
||||
public ICommand? BtnStartVideoConcatCommand { get; set; }
|
||||
public ICommand? BtnChooseAuditImageCommand { get; set; }
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
|
||||
|
||||
public ExtractWindowModel()
|
||||
{
|
||||
_dispatcher = Dispatcher.CurrentDispatcher;
|
||||
}
|
||||
|
||||
public void SetCanStart()
|
||||
{
|
||||
if (videos.Length > 0)
|
||||
{
|
||||
CanStart = true;
|
||||
}
|
||||
else
|
||||
{
|
||||
CanStart = false;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
56
Models/MainWindowModel.cs
Normal file
56
Models/MainWindowModel.cs
Normal file
@ -0,0 +1,56 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.ComponentModel;
|
||||
using System.Globalization;
|
||||
using System.Linq;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows.Data;
|
||||
|
||||
namespace VideoConcat.Models
|
||||
{
|
||||
class MainWindowModel : INotifyPropertyChanged
|
||||
{
|
||||
public enum OptionType { none, video, extract }
|
||||
|
||||
private OptionType _selectedOption;
|
||||
public OptionType SelectedOption
|
||||
{
|
||||
get => _selectedOption;
|
||||
set
|
||||
{
|
||||
_selectedOption = value;
|
||||
OnPropertyChanged();
|
||||
// 状态变化时执行逻辑
|
||||
HandleSelection(value);
|
||||
}
|
||||
}
|
||||
|
||||
private void HandleSelection(OptionType option)
|
||||
{
|
||||
Console.WriteLine($"选中了: {option}");
|
||||
}
|
||||
|
||||
|
||||
public event PropertyChangedEventHandler? PropertyChanged;
|
||||
|
||||
protected virtual void OnPropertyChanged([CallerMemberName] string? propertyName = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
|
||||
}
|
||||
}
|
||||
|
||||
public class EnumToBooleanConverter : IValueConverter
|
||||
{
|
||||
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return value?.Equals(parameter) ?? false;
|
||||
}
|
||||
|
||||
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
|
||||
{
|
||||
return (bool)value ? parameter : System.Windows.Data.Binding.DoNothing;
|
||||
}
|
||||
}
|
||||
}
|
||||
109
Services/Video/VideoProcess.cs
Normal file
109
Services/Video/VideoProcess.cs
Normal file
@ -0,0 +1,109 @@
|
||||
using FFMpegCore;
|
||||
using FFMpegCore.Enums;
|
||||
using System;
|
||||
using System.IO;
|
||||
using System.Threading.Tasks;
|
||||
using VideoConcat.Common.Tools;
|
||||
using static System.Windows.Forms.DataFormats;
|
||||
|
||||
namespace VideoConcat.Services.Video
|
||||
{
|
||||
public class VideoProcess
|
||||
{
|
||||
/// <summary>
|
||||
/// 同步删除视频指定帧和对应音频片段
|
||||
/// </summary>
|
||||
/// <param name="inputPath">输入文件路径</param>
|
||||
/// <param name="outputPath">输出文件路径</param>
|
||||
/// <param name="frameNumber">要删除的帧编号(从1开始)</param>
|
||||
/// <returns>操作是否成功</returns>
|
||||
public static async Task<bool> RemoveFrameRandomeAsync(string inputPath, string outputPath)
|
||||
{
|
||||
if (!File.Exists(inputPath))
|
||||
return false;
|
||||
|
||||
try
|
||||
{
|
||||
// 1. 获取视频信息
|
||||
var mediaInfo = await FFProbe.AnalyseAsync(inputPath);
|
||||
var videoStream = mediaInfo.PrimaryVideoStream;
|
||||
if (videoStream == null)
|
||||
{
|
||||
Console.WriteLine("没有找到视频流");
|
||||
return false;
|
||||
}
|
||||
|
||||
bool isHevc = videoStream.CodecName == "hevc";
|
||||
|
||||
// 2. 创建临时目录
|
||||
string tempDir = Path.Combine(Path.GetTempPath(), Guid.NewGuid().ToString());
|
||||
Directory.CreateDirectory(tempDir);
|
||||
|
||||
if (isHevc)
|
||||
{
|
||||
try
|
||||
{
|
||||
|
||||
// 临时文件路径
|
||||
string videoConvert = Path.Combine(tempDir, "convert.mp4");
|
||||
|
||||
await FFMpegArguments.FromFileInput(inputPath)
|
||||
.OutputToFile(videoConvert, true, opt => // 设置输出格式
|
||||
opt.WithVideoCodec("libx264")
|
||||
).ProcessAsynchronously();
|
||||
mediaInfo = await FFProbe.AnalyseAsync(videoConvert);
|
||||
|
||||
inputPath = videoConvert;
|
||||
}
|
||||
catch (Exception)
|
||||
{
|
||||
File.Delete(outputPath);
|
||||
}
|
||||
}
|
||||
|
||||
// 视频总时长(秒)
|
||||
var totalDuration = mediaInfo.Duration.TotalSeconds;
|
||||
// 计算帧时间参数
|
||||
double frameRate = videoStream.FrameRate;
|
||||
double frameDuration = 1.0 / frameRate; // 一帧时长(秒)
|
||||
|
||||
int totalFram = (int)(totalDuration * frameRate);
|
||||
// 2. 随机生成要删除的帧的时间点(避开最后一帧,防止越界)
|
||||
var random = new Random();
|
||||
var randomFrame = random.Next(20, totalFram - 10);
|
||||
|
||||
double frameTime = (randomFrame - 1) * frameDuration; // 目标帧开始时间
|
||||
double nextFrameTime = frameTime + frameDuration; // 下一帧开始时间
|
||||
|
||||
|
||||
// 临时文件路径
|
||||
string videoPart1 = Path.Combine(tempDir, "video_part1.mp4");
|
||||
string videoPart2 = Path.Combine(tempDir, "video_part2.mp4");
|
||||
bool hasSubVideo1 = SubVideo(inputPath, videoPart1, 0, frameTime);
|
||||
bool hasSubVideo2 = SubVideo(inputPath, videoPart2, nextFrameTime, totalDuration);
|
||||
if (hasSubVideo1 && hasSubVideo2)
|
||||
{
|
||||
return JoinVideo(outputPath, [videoPart1, videoPart2]);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
LogUtils.Error("抽帧失败", ex);
|
||||
Console.WriteLine($"操作失败: {ex.Message}");
|
||||
return false;
|
||||
}
|
||||
}
|
||||
|
||||
public static bool SubVideo(string inputPath, string outputPath, Double startSec, Double endSec)
|
||||
{
|
||||
return FFMpeg.SubVideo(inputPath, outputPath, TimeSpan.FromSeconds(startSec), TimeSpan.FromSeconds(endSec));
|
||||
}
|
||||
|
||||
public static bool JoinVideo(string outPutPath, string[] videoParts)
|
||||
{
|
||||
return FFMpeg.Join(outPutPath, videoParts);
|
||||
}
|
||||
|
||||
}
|
||||
}
|
||||
@ -13,14 +13,18 @@
|
||||
</PropertyGroup>
|
||||
|
||||
<ItemGroup>
|
||||
<PackageReference Include="FFMpegCore" Version="5.1.0" />
|
||||
<PackageReference Include="log4net" Version="3.0.2" />
|
||||
<PackageReference Include="FFMpegCore" Version="5.2.0" />
|
||||
<PackageReference Include="LiveCharts" Version="0.9.7" />
|
||||
<PackageReference Include="LiveCharts.Wpf" Version="0.9.7" />
|
||||
<PackageReference Include="log4net" Version="3.1.0" />
|
||||
<PackageReference Include="MahApps.Metro.IconPacks.Core" Version="6.0.0" />
|
||||
<PackageReference Include="MahApps.Metro.IconPacks.Material" Version="6.0.0" />
|
||||
<PackageReference Include="MaterialDesignXaml.DialogsHelper" Version="1.0.4" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="8.0.1" />
|
||||
<PackageReference Include="Microsoft.Extensions.Logging" Version="9.0.8" />
|
||||
<PackageReference Include="Newtonsoft.Json" Version="13.0.3" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="9.0.0" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.0" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.0" />
|
||||
<PackageReference Include="System.IO.Pipelines" Version="9.0.8" />
|
||||
<PackageReference Include="System.Text.Encodings.Web" Version="9.0.8" />
|
||||
<PackageReference Include="System.Text.Json" Version="9.0.8" />
|
||||
<PackageReference Include="WPFDevelopers" Version="0.0.0.1" />
|
||||
</ItemGroup>
|
||||
|
||||
|
||||
99
ViewModels/ExtractWindowViewModel.cs
Normal file
99
ViewModels/ExtractWindowViewModel.cs
Normal file
@ -0,0 +1,99 @@
|
||||
using System.Windows.Input;
|
||||
using VideoConcat.Models;
|
||||
using MessageBox = System.Windows.MessageBox;
|
||||
using VideoConcat.Common.Tools;
|
||||
using System.IO;
|
||||
using Microsoft.Expression.Drawing.Core;
|
||||
using FFMpegCore;
|
||||
using FFMpegCore.Enums;
|
||||
using static VideoConcat.Models.VideoModel;
|
||||
using System.Windows.Threading;
|
||||
using System.Windows;
|
||||
using VideoConcat.Services.Video;
|
||||
|
||||
namespace VideoConcat.ViewModels
|
||||
{
|
||||
public class ExtractWindowViewModel
|
||||
{
|
||||
private ExtractWindowModel _extractWindowModel;
|
||||
|
||||
public List<ConcatVideo> ConcatVideos { get; set; } = [];
|
||||
|
||||
public ExtractWindowModel ExtractWindowModel
|
||||
{
|
||||
get { return _extractWindowModel; }
|
||||
set
|
||||
{
|
||||
_extractWindowModel = value;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
|
||||
public ExtractWindowViewModel()
|
||||
{
|
||||
ExtractWindowModel = new ExtractWindowModel
|
||||
{
|
||||
CanStart = false,
|
||||
IsStart = false,
|
||||
IsCanOperate = true,
|
||||
|
||||
BtnOpenFolderCommand = new Command()
|
||||
{
|
||||
DoExcue = obj =>
|
||||
{
|
||||
FolderBrowserDialog folderBrowserDialog = new();
|
||||
if (folderBrowserDialog.ShowDialog() == DialogResult.OK)
|
||||
{
|
||||
ExtractWindowModel.FolderPath = folderBrowserDialog.SelectedPath;
|
||||
LogUtils.Info($"获取视频文件夹,视频路径:{ExtractWindowModel.FolderPath}");
|
||||
ListFolder();
|
||||
}
|
||||
}
|
||||
|
||||
},
|
||||
|
||||
BtnStartVideoConcatCommand = new Command()
|
||||
{
|
||||
DoExcue = obj =>
|
||||
{
|
||||
ExtractWindowModel.HelpInfo = "";
|
||||
Task.Run(action: () =>
|
||||
{
|
||||
ExtractWindowModel.videos.ForEach(async (video) =>
|
||||
{
|
||||
// 实例化并调用
|
||||
var remover = new VideoProcess();
|
||||
// 删除4秒处的帧(需根据实际帧位置调整)
|
||||
string _tmpPath = Path.GetDirectoryName(video) ?? "";
|
||||
string _tmpFileName = $"抽帧视频-{Path.GetFileName(video)}";
|
||||
await VideoProcess.RemoveFrameRandomeAsync(video, $"{_tmpPath}\\{_tmpFileName}");
|
||||
});
|
||||
});
|
||||
|
||||
ExtractWindowModel.HelpInfo = "全部完成!";
|
||||
}
|
||||
}
|
||||
};
|
||||
}
|
||||
|
||||
private void ListFolder()
|
||||
{
|
||||
DirectoryInfo dir = new(ExtractWindowModel.FolderPath);
|
||||
try
|
||||
{
|
||||
DirectoryInfo dirD = dir as DirectoryInfo;
|
||||
|
||||
//获取文件夹下所有视频文件
|
||||
|
||||
ExtractWindowModel.videos = Directory.GetFiles(dirD.FullName, "*.mp4");
|
||||
ExtractWindowModel.SetCanStart();
|
||||
}
|
||||
catch (Exception ex)
|
||||
{
|
||||
MessageBox.Show(ex.Message);
|
||||
return;
|
||||
}
|
||||
}
|
||||
}
|
||||
}
|
||||
19
ViewModels/MainWindowViewModel.cs
Normal file
19
ViewModels/MainWindowViewModel.cs
Normal file
@ -0,0 +1,19 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using VideoConcat.Models;
|
||||
|
||||
namespace VideoConcat.ViewModels
|
||||
{
|
||||
class MainWindowViewModel
|
||||
{
|
||||
private MainWindowModel _mainWindowModel;
|
||||
public MainWindowModel MainWindowModel
|
||||
{
|
||||
get { return _mainWindowModel; }
|
||||
set { _mainWindowModel = value; }
|
||||
}
|
||||
}
|
||||
}
|
||||
43
Views/ExtractWindow.xaml
Normal file
43
Views/ExtractWindow.xaml
Normal file
@ -0,0 +1,43 @@
|
||||
<UserControl x:Class="VideoConcat.Views.ExtractWindow"
|
||||
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:VideoConcat.Views"
|
||||
xmlns:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
|
||||
mc:Ignorable="d"
|
||||
Height="800" Width="1000">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Red.xaml" />
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml" />
|
||||
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</UserControl.Resources>
|
||||
<Border CornerRadius="5" BorderBrush="White" BorderThickness="2,2,2,2">
|
||||
<Grid>
|
||||
|
||||
<Grid.RowDefinitions>
|
||||
<RowDefinition Height="40"></RowDefinition>
|
||||
<RowDefinition Height="*"></RowDefinition>
|
||||
</Grid.RowDefinitions>
|
||||
<Border>
|
||||
<WrapPanel>
|
||||
<Label VerticalAlignment="Center" Width="100" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">视频文件夹:</Label>
|
||||
<TextBox Grid.Column="1" Width="650" Name="FoldPath" Text="{Binding ExtractWindowModel.FolderPath,Mode=TwoWay}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" materialDesign:HintAssist.Hint="选择包含需要处理的视频文件夹"/>
|
||||
<Button Grid.Column="2" Width="100" Content="选择" FontSize="16" Command="{Binding ExtractWindowModel.BtnOpenFolderCommand}" Background="#40568D" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择含有视频的主文件夹" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2" IsEnabled="{Binding ExtractWindowModel.IsCanOperate}"/>
|
||||
<Button Grid.Column="3" Width="100" Content="处理" FontSize="16" Command="{Binding ExtractWindowModel.BtnStartVideoConcatCommand}" Background="#3B94FE" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="开始处理视频" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2,0,2" IsEnabled="{Binding ExtractWindowModel.CanStart}"/>
|
||||
</WrapPanel>
|
||||
</Border>
|
||||
|
||||
<Border Grid.Row="1">
|
||||
<TextBlock Text="{Binding ExtractWindowModel.HelpInfo,Mode=TwoWay}"></TextBlock>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</UserControl>
|
||||
29
Views/ExtractWindow.xaml.cs
Normal file
29
Views/ExtractWindow.xaml.cs
Normal file
@ -0,0 +1,29 @@
|
||||
using System;
|
||||
using System.Collections.Generic;
|
||||
using System.Linq;
|
||||
using System.Text;
|
||||
using System.Threading.Tasks;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Documents;
|
||||
using System.Windows.Input;
|
||||
using System.Windows.Media;
|
||||
using System.Windows.Media.Imaging;
|
||||
using System.Windows.Shapes;
|
||||
using VideoConcat.ViewModels;
|
||||
|
||||
namespace VideoConcat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// ExtractWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class ExtractWindow : System.Windows.Controls.UserControl
|
||||
{
|
||||
public ExtractWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext = new ExtractWindowViewModel();
|
||||
}
|
||||
}
|
||||
}
|
||||
94
Views/LoginWindow.xaml
Normal file
94
Views/LoginWindow.xaml
Normal file
@ -0,0 +1,94 @@
|
||||
<Window x:Class="VideoConcat.Views.LoginWindow"
|
||||
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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:helpers="clr-namespace:VideoConcat.Helpers"
|
||||
xmlns:local="clr-namespace:VideoConcat"
|
||||
mc:Ignorable="d"
|
||||
Title="登录"
|
||||
Height="330"
|
||||
Width="500"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Red.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml"/>
|
||||
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="39*"/>
|
||||
<ColumnDefinition Width="461*"/>
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.ColumnSpan="2">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Width="500">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="20"
|
||||
FontFamily="Great Vibes"
|
||||
FontSize="38"
|
||||
TextAlignment="Center">
|
||||
用户登录
|
||||
</TextBlock>
|
||||
<StackPanel Margin="10"
|
||||
Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Width="30" Height="30"
|
||||
Kind="User" Margin="10,0,10,0"/>
|
||||
<TextBox x:Name="Username" Width="400"
|
||||
Margin="10,0" BorderBrush="White"
|
||||
CaretBrush="#FFD94448"
|
||||
SelectionBrush="#FFD94448"
|
||||
materialDesign:HintAssist.Hint="输入 用户名"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10"
|
||||
Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Width="30" Height="30"
|
||||
Kind="Lock" Margin="10,0,10,0"/>
|
||||
<PasswordBox
|
||||
Width="400"
|
||||
Margin="10,0" BorderBrush="White"
|
||||
CaretBrush="#FFD94448"
|
||||
SelectionBrush="#FFD94448"
|
||||
materialDesign:HintAssist.Hint="输入 密码"
|
||||
x:Name="Password"/>
|
||||
<PasswordBox
|
||||
Width="400"
|
||||
Margin="10,0"
|
||||
BorderBrush="White"
|
||||
CaretBrush="#FFD94448"
|
||||
SelectionBrush="#FFD94448"
|
||||
materialDesign:HintAssist.Hint="输入 密码"
|
||||
helpers:PasswordBoxHelper.BindPassword="True"
|
||||
helpers:PasswordBoxHelper.BoundPassword="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
|
||||
</PasswordBox>
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10" Orientation="Horizontal">
|
||||
<CheckBox HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="30" x:Name="ckbRemember" Width="30" Height="30" Margin="15,0,10,0" IsChecked="True"></CheckBox>
|
||||
<TextBlock VerticalAlignment="Center" Margin="10,0">记住我</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Button x:Name="btnLogin" Width="100" Height="40"
|
||||
materialDesign:ButtonAssist.CornerRadius="2"
|
||||
Background="#40568D" BorderBrush="#7F7F7F" BorderThickness="2"
|
||||
Content="登录" ToolTip="登录"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}" Click="BtnLogin_Click"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
</StackPanel>
|
||||
|
||||
</Border>
|
||||
</Grid>
|
||||
</Window>
|
||||
67
Views/LoginWindow.xaml.cs
Normal file
67
Views/LoginWindow.xaml.cs
Normal file
@ -0,0 +1,67 @@
|
||||
using System.Net;
|
||||
using System.Windows;
|
||||
using VideoConcat.Common.Api.Base;
|
||||
using VideoConcat.Common.Tools;
|
||||
|
||||
namespace VideoConcat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// </summary>
|
||||
public partial class LoginWindow : Window
|
||||
{
|
||||
public LoginWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Username.Text = Config.GetSettingString("userName");
|
||||
Password.Password = Config.GetSettingString("password");
|
||||
ckbRemember.IsChecked = Config.GetSettingString("isRemember") == "true";
|
||||
}
|
||||
|
||||
private void BtnExit_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
}
|
||||
|
||||
private async void BtnLogin_Click(object sender, RoutedEventArgs e)
|
||||
{
|
||||
|
||||
string _userName = Username.Text;
|
||||
bool _isChecked = Convert.ToBoolean(ckbRemember.IsChecked);
|
||||
string _password = Password.Password;
|
||||
|
||||
|
||||
if (string.IsNullOrEmpty(_userName) || string.IsNullOrEmpty(_password))
|
||||
{
|
||||
Username.Clear();
|
||||
Password.Clear();
|
||||
WPFDevelopers.Controls.MessageBox.Show("请输入用户名或者密码!");
|
||||
return;
|
||||
}
|
||||
ApiResponse<UserLoginResponse> res = await SystemApi.LoginAsync<UserLoginResponse>(_userName, _password);
|
||||
if (res.Code != 0)
|
||||
{
|
||||
WPFDevelopers.Controls.MessageBox.Show(res.Msg);
|
||||
}
|
||||
else
|
||||
{
|
||||
if (_isChecked)
|
||||
{
|
||||
Config.UpdateSettingString("userName", _userName);
|
||||
Config.UpdateSettingString("password", _password);
|
||||
Config.UpdateSettingString("isRemember", "true");
|
||||
}
|
||||
else
|
||||
{
|
||||
Config.UpdateSettingString("userName", "");
|
||||
Config.UpdateSettingString("password", "");
|
||||
Config.UpdateSettingString("isRemember", "false");
|
||||
}
|
||||
|
||||
new MainWindow().Show();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
}
|
||||
@ -1,94 +1,141 @@
|
||||
<Window x:Class="VideoConcat.Views.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:materialDesign="http://materialdesigninxaml.net/winfx/xaml/themes"
|
||||
xmlns:helpers="clr-namespace:VideoConcat.Helpers"
|
||||
xmlns:local="clr-namespace:VideoConcat"
|
||||
mc:Ignorable="d"
|
||||
Title="登录"
|
||||
Height="330"
|
||||
Width="500"
|
||||
ResizeMode="NoResize"
|
||||
WindowStartupLocation="CenterScreen">
|
||||
<Window.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Defaults.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Primary/MaterialDesignColor.Red.xaml"/>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignColors;component/Themes/Recommended/Accent/MaterialDesignColor.Lime.xaml"/>
|
||||
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
|
||||
xmlns:Icon="http://metro.mahapps.com/winfx/xaml/iconpacks"
|
||||
xmlns:lvc="clr-namespace:LiveCharts.Wpf;assembly=LiveCharts.Wpf"
|
||||
xmlns:local="clr-namespace:VideoConcat.Views"
|
||||
xmlns:vm="clr-namespace:VideoConcat.ViewModels"
|
||||
xmlns:conv="clr-namespace:VideoConcat.Conversions"
|
||||
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
mc:Ignorable="d"
|
||||
Width="1100" Height="800" WindowStartupLocation="CenterScreen"
|
||||
ResizeMode="NoResize"
|
||||
Title="工具">
|
||||
<Window.Resources>
|
||||
<Style x:Key="BottomButton" TargetType="Button">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
<Setter Property="Width" Value="50"/>
|
||||
<Setter Property="Height" Value="50"/>
|
||||
<Setter Property="BorderBrush" Value="White"/>
|
||||
<Setter Property="BorderThickness" Value="2,2,2,2"/>
|
||||
|
||||
<Setter Property="Margin" Value="1"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="Button">
|
||||
<Border Background="{TemplateBinding Background}" CornerRadius="5">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#5a5080"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" Value="#FFFFFF"/>
|
||||
<Setter Property="BorderBrush" Value="GreenYellow"/>
|
||||
<Setter Property="BorderThickness" Value="2,2,2,2"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
<Style x:Key="MenuButton" TargetType="RadioButton">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="#FFFFFF"/>
|
||||
<Setter Property="Width" Value="50"/>
|
||||
<Setter Property="Height" Value="50"/>
|
||||
<Setter Property="BorderBrush" Value="Black"/>
|
||||
<Setter Property="BorderThickness" Value="2,2,2,2"/>
|
||||
|
||||
<Setter Property="Margin" Value="1"/>
|
||||
<Setter Property="FocusVisualStyle" Value="{x:Null}"/>
|
||||
<Setter Property="Template">
|
||||
<Setter.Value>
|
||||
<ControlTemplate TargetType="RadioButton">
|
||||
|
||||
<Border Background="{TemplateBinding Background}" CornerRadius="5">
|
||||
<ContentPresenter HorizontalAlignment="Center" VerticalAlignment="Center"/>
|
||||
</Border>
|
||||
</ControlTemplate>
|
||||
</Setter.Value>
|
||||
</Setter>
|
||||
<Style.Triggers>
|
||||
<Trigger Property="IsMouseOver" Value="True">
|
||||
<Setter Property="Background" Value="#5a5080"/>
|
||||
</Trigger>
|
||||
<Trigger Property="IsChecked" Value="True">
|
||||
<Setter Property="Background" Value="Brown"/>
|
||||
<Setter Property="BorderBrush" Value="Black"/>
|
||||
<Setter Property="BorderThickness" Value="2,2,2,2"/>
|
||||
</Trigger>
|
||||
<!-- 按下状态 -->
|
||||
<Trigger Property="IsPressed" Value="True">
|
||||
<Setter Property="Background" Value="#D0D0D0"/>
|
||||
</Trigger>
|
||||
</Style.Triggers>
|
||||
</Style>
|
||||
|
||||
<Style x:Key="MenuButtonIcon" TargetType="Icon:PackIconMaterial">
|
||||
<Setter Property="Background" Value="Transparent"/>
|
||||
<Setter Property="Foreground" Value="White"/>
|
||||
<Setter Property="BorderBrush" Value="White"/>
|
||||
<Setter Property="Width" Value="24"/>
|
||||
<Setter Property="Height" Value="18"/>
|
||||
</Style>
|
||||
</Window.Resources>
|
||||
|
||||
<Border Background="#cfd5e5" CornerRadius="5" BorderThickness="2" BorderBrush="#ebedf3" Padding="2" MouseDown="Border_MouseDown">
|
||||
<Border CornerRadius="5">
|
||||
<Border.Background>
|
||||
<LinearGradientBrush StartPoint="0,0" EndPoint="0,1">
|
||||
<GradientStop Color="#fefefe" Offset="0" />
|
||||
<GradientStop Color="#ededef" Offset="1" />
|
||||
</LinearGradientBrush>
|
||||
</Border.Background>
|
||||
|
||||
<Grid>
|
||||
<Grid.ColumnDefinitions>
|
||||
<ColumnDefinition Width="39*"/>
|
||||
<ColumnDefinition Width="461*"/>
|
||||
<ColumnDefinition Width="70" />
|
||||
<ColumnDefinition Width="*" />
|
||||
</Grid.ColumnDefinitions>
|
||||
<Border Grid.ColumnSpan="2">
|
||||
<StackPanel Orientation="Horizontal">
|
||||
<StackPanel Width="500">
|
||||
<StackPanel>
|
||||
<TextBlock Margin="20"
|
||||
FontFamily="Great Vibes"
|
||||
FontSize="38"
|
||||
TextAlignment="Center">
|
||||
用户登录
|
||||
</TextBlock>
|
||||
<StackPanel Margin="10"
|
||||
Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Width="30" Height="30"
|
||||
Kind="User" Margin="10,0,10,0"/>
|
||||
<TextBox x:Name="Username" Width="400"
|
||||
Margin="10,0" BorderBrush="White"
|
||||
CaretBrush="#FFD94448"
|
||||
SelectionBrush="#FFD94448"
|
||||
materialDesign:HintAssist.Hint="输入 用户名"/>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10"
|
||||
Orientation="Horizontal">
|
||||
<materialDesign:PackIcon
|
||||
Width="30" Height="30"
|
||||
Kind="Lock" Margin="10,0,10,0"/>
|
||||
<PasswordBox
|
||||
Width="400"
|
||||
Margin="10,0" BorderBrush="White"
|
||||
CaretBrush="#FFD94448"
|
||||
SelectionBrush="#FFD94448"
|
||||
materialDesign:HintAssist.Hint="输入 密码"
|
||||
x:Name="Password"/>
|
||||
<PasswordBox
|
||||
Width="400"
|
||||
Margin="10,0"
|
||||
BorderBrush="White"
|
||||
CaretBrush="#FFD94448"
|
||||
SelectionBrush="#FFD94448"
|
||||
materialDesign:HintAssist.Hint="输入 密码"
|
||||
helpers:PasswordBoxHelper.BindPassword="True"
|
||||
helpers:PasswordBoxHelper.BoundPassword="{Binding Password, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
|
||||
</PasswordBox>
|
||||
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10" Orientation="Horizontal">
|
||||
<CheckBox HorizontalAlignment="Right" VerticalAlignment="Center" FontSize="30" x:Name="ckbRemember" Width="30" Height="30" Margin="15,0,10,0" IsChecked="True"></CheckBox>
|
||||
<TextBlock VerticalAlignment="Center" Margin="10,0">记住我</TextBlock>
|
||||
</StackPanel>
|
||||
<StackPanel Margin="10" HorizontalAlignment="Center" VerticalAlignment="Center">
|
||||
<Button x:Name="btnLogin" Width="100" Height="40"
|
||||
materialDesign:ButtonAssist.CornerRadius="2"
|
||||
Background="#40568D" BorderBrush="#7F7F7F" BorderThickness="2"
|
||||
Content="登录" ToolTip="登录"
|
||||
Style="{StaticResource MaterialDesignRaisedButton}" Click="BtnLogin_Click"/>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
|
||||
<!--Left Menu-->
|
||||
<Border Background="#7163ba" CornerRadius="5" BorderThickness="2" BorderBrush="#ebedf3" Margin="2">
|
||||
<Grid>
|
||||
<StackPanel VerticalAlignment="Top">
|
||||
<RadioButton GroupName="OptionsGroup" Name="video" Style="{StaticResource MenuButton}" Checked="RadioButton_Checked" >
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<Icon:PackIconMaterial Kind="VideoBox" Style="{StaticResource MenuButtonIcon}"/>
|
||||
<TextBlock>视频</TextBlock>
|
||||
</StackPanel>
|
||||
</RadioButton>
|
||||
<Separator></Separator>
|
||||
<RadioButton GroupName="OptionsGroup" Name="extract" Style="{StaticResource MenuButton}" Checked="RadioButton_Checked">
|
||||
<StackPanel HorizontalAlignment="Center">
|
||||
<Icon:PackIconMaterial Kind="VideoCheck" Style="{StaticResource MenuButtonIcon}"/>
|
||||
<TextBlock>抽帧</TextBlock>
|
||||
</StackPanel>
|
||||
</RadioButton>
|
||||
<Separator></Separator>
|
||||
</StackPanel>
|
||||
<StackPanel VerticalAlignment="Bottom">
|
||||
<Button Style="{StaticResource BottomButton}">
|
||||
<Icon:PackIconMaterial Kind="Account" Style="{StaticResource MenuButtonIcon}"/>
|
||||
</Button>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Border>
|
||||
|
||||
<!--Main Section-->
|
||||
<Border Grid.Column="1" CornerRadius="5" BorderThickness="2" BorderBrush="#ebedf3" Margin="2">
|
||||
<Grid x:Name="mainGrid">
|
||||
</Grid>
|
||||
</Border>
|
||||
</Grid>
|
||||
</Border>
|
||||
</Border>
|
||||
</Window>
|
||||
|
||||
@ -1,64 +1,101 @@
|
||||
using System.Windows;
|
||||
using VideoConcat.Common.Api.Base;
|
||||
using VideoConcat.Common.Tools;
|
||||
using System.Globalization;
|
||||
using System.Windows;
|
||||
using System.Windows.Controls;
|
||||
using System.Windows.Data;
|
||||
using System.Windows.Input;
|
||||
using VideoConcat.Models;
|
||||
using RadioButton = System.Windows.Controls.RadioButton;
|
||||
|
||||
namespace VideoConcat.Views
|
||||
{
|
||||
/// <summary>
|
||||
/// Interaction logic for MainWindow.xaml
|
||||
/// MainWindow.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class MainWindow : Window
|
||||
{
|
||||
|
||||
|
||||
public MainWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
Username.Text = Config.GetSettingString("userName");
|
||||
Password.Password = Config.GetSettingString("password");
|
||||
ckbRemember.IsChecked = Config.GetSettingString("isRemember") == "true";
|
||||
this.DataContext = new MainWindowModel();
|
||||
// 窗口加载完成后执行
|
||||
Loaded += MainView_Loaded;
|
||||
}
|
||||
|
||||
private void BtnExit_Click(object sender, RoutedEventArgs e)
|
||||
public void MainView_Loaded(object sender, RoutedEventArgs e)
|
||||
{
|
||||
Close();
|
||||
// 1. 为目标Grid创建列定义
|
||||
SetupGridColumns(mainGrid);
|
||||
|
||||
// 2. 实例化已有视图(或获取已存在的视图实例)
|
||||
var existingView = new VideoWindow(); // 这里是已有视图的实例
|
||||
|
||||
// 3. 将视图添加到指定列中(例如第1列,索引为1)
|
||||
AddViewToColumn(mainGrid, existingView);
|
||||
}
|
||||
|
||||
private async void BtnLogin_Click(object sender, RoutedEventArgs e)
|
||||
/// <summary>
|
||||
/// 为Grid设置列定义
|
||||
/// </summary>
|
||||
private void SetupGridColumns(Grid grid)
|
||||
{
|
||||
// 清空现有列(可选)
|
||||
grid.Children.Clear();
|
||||
}
|
||||
|
||||
|
||||
/// <summary>
|
||||
/// 将视图添加到Grid的指定列
|
||||
/// </summary>
|
||||
/// <param name="grid">目标Grid</param>
|
||||
/// <param name="view">要添加的视图(UserControl/FrameworkElement)</param>
|
||||
/// <param name="columnIndex">列索引(从0开始)</param>
|
||||
private void AddViewToColumn(Grid grid, FrameworkElement view)
|
||||
{
|
||||
|
||||
string _userName = Username.Text;
|
||||
bool _isChecked = Convert.ToBoolean(ckbRemember.IsChecked);
|
||||
string _password = Password.Password;
|
||||
// 将视图添加到Grid的子元素中
|
||||
grid.Children.Add(view);
|
||||
}
|
||||
|
||||
if (string.IsNullOrEmpty(_userName) || string.IsNullOrEmpty(_password))
|
||||
private void Border_MouseDown(object sender, MouseButtonEventArgs e)
|
||||
{
|
||||
Username.Clear();
|
||||
Password.Clear();
|
||||
WPFDevelopers.Controls.MessageBox.Show("请输入用户名或者密码!");
|
||||
return;
|
||||
|
||||
if (e.ChangedButton == MouseButton.Left)
|
||||
{
|
||||
this.DragMove();
|
||||
}
|
||||
ApiResponse<UserLoginResponse> res = await SystemApi.LoginAsync<UserLoginResponse>(_userName, _password);
|
||||
if (res.Code != 0)
|
||||
{
|
||||
WPFDevelopers.Controls.MessageBox.Show(res.Msg);
|
||||
}
|
||||
else
|
||||
|
||||
|
||||
private void RadioButton_Checked(object sender, RoutedEventArgs e)
|
||||
{
|
||||
if (_isChecked)
|
||||
if (sender is RadioButton radioButton)
|
||||
{
|
||||
Config.UpdateSettingString("userName", _userName);
|
||||
Config.UpdateSettingString("password", _password);
|
||||
Config.UpdateSettingString("isRemember", "true");
|
||||
if (radioButton.Name == "extract")
|
||||
{
|
||||
SetupGridColumns(mainGrid);
|
||||
// 2. 实例化已有视图(或获取已存在的视图实例)
|
||||
var existingView = new ExtractWindow(); // 这里是已有视图的实例
|
||||
|
||||
// 3. 将视图添加到指定列中(例如第1列,索引为1)
|
||||
AddViewToColumn(mainGrid, existingView);
|
||||
}
|
||||
else
|
||||
|
||||
if (radioButton.Name == "video")
|
||||
{
|
||||
Config.UpdateSettingString("userName", "");
|
||||
Config.UpdateSettingString("password", "");
|
||||
Config.UpdateSettingString("isRemember", "false");
|
||||
// 1. 为目标Grid创建列定义
|
||||
SetupGridColumns(mainGrid);
|
||||
|
||||
// 2. 实例化已有视图(或获取已存在的视图实例)
|
||||
var existingView = new VideoWindow(); // 这里是已有视图的实例
|
||||
|
||||
// 3. 将视图添加到指定列中(例如第1列,索引为1)
|
||||
AddViewToColumn(mainGrid, existingView);
|
||||
}
|
||||
new Video().Show();
|
||||
Close();
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
}
|
||||
|
||||
@ -1,4 +1,4 @@
|
||||
<Window x:Name="视频拼接" x:Class="VideoConcat.Views.Video"
|
||||
<UserControl x:Name="视频拼接" x:Class="VideoConcat.Views.VideoWindow"
|
||||
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"
|
||||
@ -7,8 +7,8 @@
|
||||
xmlns:wd="https://github.com/WPFDevelopersOrg/WPFDevelopers"
|
||||
xmlns:local="clr-namespace:VideoConcat.Views"
|
||||
mc:Ignorable="d"
|
||||
Title="视频拼接" Height="800" Width="780" WindowStartupLocation="CenterScreen" ResizeMode="CanMinimize">
|
||||
<Window.Resources>
|
||||
Height="800" Width="1000">
|
||||
<UserControl.Resources>
|
||||
<ResourceDictionary>
|
||||
<ResourceDictionary.MergedDictionaries>
|
||||
<ResourceDictionary Source="pack://application:,,,/MaterialDesignThemes.Wpf;component/Themes/MaterialDesignTheme.Light.xaml"/>
|
||||
@ -18,18 +18,18 @@
|
||||
|
||||
</ResourceDictionary.MergedDictionaries>
|
||||
</ResourceDictionary>
|
||||
</Window.Resources>
|
||||
</UserControl.Resources>
|
||||
<Grid>
|
||||
<StackPanel >
|
||||
<WrapPanel Height="120">
|
||||
<Label VerticalAlignment="Center" Width="100" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">视频文件夹:</Label>
|
||||
<TextBox Grid.Column="1" Width="500" Name="FoldPath" Text="{Binding VideoModel.FolderPath,Mode=TwoWay}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" materialDesign:HintAssist.Hint="选择视频主文件夹"/>
|
||||
<TextBox Grid.Column="1" Width="740" Name="FoldPath" Text="{Binding VideoModel.FolderPath,Mode=TwoWay}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" materialDesign:HintAssist.Hint="选择视频主文件夹"/>
|
||||
<Button Grid.Column="2" Width="100" Content="选 择" FontSize="16" Command="{Binding VideoModel.BtnOpenFolderCommand}" Background="#40568D" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择含有视频的主文件夹" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2" IsEnabled="{Binding VideoModel.IsCanOperate}"/>
|
||||
<Label Grid.Row="1" Width="100" VerticalAlignment="Center" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">选择广审:</Label>
|
||||
<TextBox Grid.Row="1" Width="500" Grid.Column="1" Text="{Binding VideoModel.AuditImagePath,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请选择" materialDesign:HintAssist.Hint="请选择"/>
|
||||
<TextBox Grid.Row="1" Width="740" Grid.Column="1" Text="{Binding VideoModel.AuditImagePath,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" IsReadOnly="True" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请选择" materialDesign:HintAssist.Hint="请选择"/>
|
||||
<Button Grid.Row="1" Width="100" Grid.Column="2" Content="选择文件" FontSize="16" Command="{Binding VideoModel.BtnChooseAuditImageCommand}" Background="#E54858" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="选择广审" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2" IsEnabled="{Binding VideoModel.IsCanOperate}"/>
|
||||
<Label Grid.Row="1" Width="100" VerticalAlignment="Center" FontSize="16" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" Style="{StaticResource MaterialDesignLabel}" VerticalContentAlignment="Stretch">视频个数:</Label>
|
||||
<TextBox Grid.Row="1" Width="500" Grid.Column="1" Text="{Binding VideoModel.Num,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请输入合成视频个数" materialDesign:HintAssist.Hint="请输入拼接视频数目" IsEnabled="{Binding VideoModel.IsCanOperate}" />
|
||||
<TextBox Grid.Row="1" Width="740" Grid.Column="1" Text="{Binding VideoModel.Num,Mode=TwoWay,UpdateSourceTrigger=PropertyChanged}" Margin="5,2" BorderBrush="#7F7F7F" BorderThickness="2" FontSize="16" VerticalContentAlignment="Center" ToolTip="请输入合成视频个数" materialDesign:HintAssist.Hint="请输入拼接视频数目" IsEnabled="{Binding VideoModel.IsCanOperate}" />
|
||||
<Button Grid.Row="1" Width="100" Grid.Column="2" Content="开始拼接" FontSize="16" Command="{Binding VideoModel.BtnStartVideoConcatCommand}" Background="#E54858" BorderBrush="#7F7F7F" BorderThickness="2" ToolTip="开始拼接视频" Style="{StaticResource MaterialDesignRaisedButton}" Margin="5,2" IsEnabled="{Binding VideoModel.CanStart}" Cursor="Hand"/>
|
||||
</WrapPanel>
|
||||
<StackPanel Orientation="Horizontal" Height="40">
|
||||
@ -69,4 +69,4 @@
|
||||
</StackPanel>
|
||||
</StackPanel>
|
||||
</Grid>
|
||||
</Window>
|
||||
</UserControl>
|
||||
@ -20,9 +20,9 @@ namespace VideoConcat.Views
|
||||
/// <summary>
|
||||
/// Video.xaml 的交互逻辑
|
||||
/// </summary>
|
||||
public partial class Video : Window
|
||||
public partial class VideoWindow : System.Windows.Controls.UserControl
|
||||
{
|
||||
public Video()
|
||||
public VideoWindow()
|
||||
{
|
||||
InitializeComponent();
|
||||
this.DataContext=new VideoViewModel();
|
||||
Loading…
Reference in New Issue
Block a user