具备界面基础功能
This commit is contained in:
@@ -0,0 +1,253 @@
|
||||
using System.Collections.ObjectModel;
|
||||
using System.ComponentModel;
|
||||
using System.Runtime.CompilerServices;
|
||||
using System.Windows;
|
||||
using System.Windows.Input;
|
||||
|
||||
namespace SHH.CameraDashboard
|
||||
{
|
||||
public class CameraImageSubscriptionViewModels : INotifyPropertyChanged
|
||||
{
|
||||
private readonly WebApiCameraModel _camera;
|
||||
|
||||
public event Action RequestClose;
|
||||
|
||||
// 用于绑定 ComboBox 的类型列表
|
||||
public Dictionary<int, string> SubscriptionTypes { get; } = new Dictionary<int, string>
|
||||
{
|
||||
{ 0, "本地窗口预览" },
|
||||
{ 1, "本地录像" },
|
||||
{ 2, "句柄渲染 (嵌入)" },
|
||||
{ 3, "网络转发 (TCP/UDP)" },
|
||||
{ 4, "Web 推流" }
|
||||
};
|
||||
|
||||
// --- 数据源 ---
|
||||
public ObservableCollection<SubscriptionDto> Subscriptions { get; set; } = new ObservableCollection<SubscriptionDto>();
|
||||
|
||||
// --- 编辑表单属性 ---
|
||||
|
||||
private string _editAppId;
|
||||
public string EditAppId
|
||||
{
|
||||
get => _editAppId;
|
||||
set { _editAppId = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _editType;
|
||||
public int EditType
|
||||
{
|
||||
get => _editType;
|
||||
set
|
||||
{
|
||||
_editType = value;
|
||||
OnPropertyChanged();
|
||||
// 切换类型时,控制 UI 上 IP/Port 输入框的显示
|
||||
OnPropertyChanged(nameof(IsNetworkType));
|
||||
OnPropertyChanged(nameof(IsRecordType));
|
||||
}
|
||||
}
|
||||
|
||||
private int _editFps = 25;
|
||||
public int EditFps
|
||||
{
|
||||
get => _editFps;
|
||||
set { _editFps = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private string _editMemo;
|
||||
public string EditMemo
|
||||
{
|
||||
get => _editMemo;
|
||||
set { _editMemo = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// 网络参数
|
||||
private string _editTargetIp = "127.0.0.1";
|
||||
public string EditTargetIp
|
||||
{
|
||||
get => _editTargetIp;
|
||||
set { _editTargetIp = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
private int _editTargetPort = 8080;
|
||||
public int EditTargetPort
|
||||
{
|
||||
get => _editTargetPort;
|
||||
set { _editTargetPort = value; OnPropertyChanged(); }
|
||||
}
|
||||
|
||||
// --- 界面显隐控制 ---
|
||||
// 只有类型是 3或4 时显示网络设置
|
||||
public bool IsNetworkType => EditType == 3 || EditType == 4;
|
||||
// 只有类型是 1 时显示录像设置 (这里简化,暂时只演示网络显隐)
|
||||
public bool IsRecordType => EditType == 1;
|
||||
|
||||
|
||||
// --- 命令 ---
|
||||
public ICommand LoadCommand { get; }
|
||||
public ICommand SaveCommand { get; }
|
||||
public ICommand DeleteCommand { get; }
|
||||
public ICommand ClearFormCommand { get; }
|
||||
|
||||
public CameraImageSubscriptionViewModels(WebApiCameraModel camera)
|
||||
{
|
||||
_camera = camera;
|
||||
|
||||
LoadCommand = new RelayCommand(ExecuteLoad);
|
||||
SaveCommand = new RelayCommand(ExecuteSave);
|
||||
DeleteCommand = new RelayCommand(ExecuteDelete);
|
||||
ClearFormCommand = new RelayCommand(obj => ResetForm());
|
||||
|
||||
// 初始化加载
|
||||
ExecuteLoad(null);
|
||||
}
|
||||
|
||||
private async void ExecuteLoad(object obj)
|
||||
{
|
||||
var list = await ApiClient.Instance.Cameras.GetSubscriptionsAsync(_camera.Id);
|
||||
Subscriptions.Clear();
|
||||
foreach (var item in list)
|
||||
{
|
||||
Subscriptions.Add(item);
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExecuteSave(object obj)
|
||||
{
|
||||
// 1. 基础校验
|
||||
if (string.IsNullOrWhiteSpace(EditAppId))
|
||||
{
|
||||
MessageBox.Show("AppId 不能为空", "提示");
|
||||
return;
|
||||
}
|
||||
|
||||
// 2. 构建 DTO
|
||||
// 注意:这里需要根据你 DTO 的定义进行类型转换和默认值处理
|
||||
var dto = new SubscriptionDto
|
||||
{
|
||||
AppId = EditAppId,
|
||||
|
||||
// ★★★ 修改:直接赋值 int,不需要强转枚举 ★★★
|
||||
Type = EditType,
|
||||
|
||||
DisplayFps = EditFps,
|
||||
Memo = EditMemo ?? string.Empty,
|
||||
|
||||
// ... 网络参数 ...
|
||||
TargetIp = IsNetworkType ? (EditTargetIp ?? string.Empty) : string.Empty,
|
||||
TargetPort = IsNetworkType ? EditTargetPort : 0,
|
||||
|
||||
// ★★★ 修改:直接赋值 int ★★★
|
||||
Protocol = 0, // 0 代表 TCP
|
||||
|
||||
// ... 其他参数 ...
|
||||
Handle = string.Empty,
|
||||
SavePath = ((SubscriptionType)EditType == SubscriptionType.LocalRecord) ? @"C:\Temp\Video" : string.Empty,
|
||||
RecordDuration = 0
|
||||
};
|
||||
|
||||
// 3. 发送请求
|
||||
bool success = await ApiClient.Instance.Cameras.UpdateSubscriptionAsync(_camera.Id, dto);
|
||||
|
||||
if (success)
|
||||
{
|
||||
MessageBox.Show("保存成功", "提示");
|
||||
ExecuteLoad(null); // 刷新列表
|
||||
// ResetForm(); // 可选:保存后清空表单
|
||||
}
|
||||
else
|
||||
{
|
||||
MessageBox.Show("保存失败,请检查网络或参数。", "错误");
|
||||
}
|
||||
}
|
||||
|
||||
private async void ExecuteDelete(object parameter)
|
||||
{
|
||||
// 支持两种方式删除:
|
||||
// 1. 传入 parameter (点击列表中的删除按钮)
|
||||
// 2. 根据当前表单的 AppId (如果在编辑模式)
|
||||
|
||||
string appIdToDelete = parameter as string;
|
||||
|
||||
if (string.IsNullOrEmpty(appIdToDelete)) return;
|
||||
|
||||
if (MessageBox.Show($"确定要停止并注销 [{appIdToDelete}] 吗?", "确认", MessageBoxButton.YesNo) != MessageBoxResult.Yes)
|
||||
return;
|
||||
|
||||
// 构造删除请求:关键是 DisplayFps = 0
|
||||
var dto = new SubscriptionDto
|
||||
{
|
||||
AppId = appIdToDelete,
|
||||
Type = 0,
|
||||
DisplayFps = 0, // <--- 核心:0 代表注销
|
||||
Memo = "User Deleted"
|
||||
};
|
||||
|
||||
bool success = await ApiClient.Instance.Cameras.UpdateSubscriptionAsync(_camera.Id, dto);
|
||||
if (success)
|
||||
{
|
||||
ExecuteLoad(null);
|
||||
}
|
||||
}
|
||||
|
||||
private void ResetForm()
|
||||
{
|
||||
// 生成一个随机 AppId 方便测试
|
||||
EditAppId = $"Client_{DateTime.Now:HHmmss}";
|
||||
EditType = 0;
|
||||
EditFps = 25;
|
||||
EditMemo = "";
|
||||
EditTargetIp = "127.0.0.1";
|
||||
EditTargetPort = 8080;
|
||||
}
|
||||
|
||||
// --- INotifyPropertyChanged 实现 (略,使用你的基类或标准实现) ---
|
||||
public event PropertyChangedEventHandler PropertyChanged;
|
||||
protected void OnPropertyChanged([CallerMemberName] string name = null)
|
||||
{
|
||||
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
|
||||
}
|
||||
|
||||
// 1. 添加一个字段
|
||||
private SubscriptionDto _selectedSubscription;
|
||||
|
||||
// 2. 添加 SelectedSubscription 属性
|
||||
public SubscriptionDto SelectedSubscription
|
||||
{
|
||||
get => _selectedSubscription;
|
||||
set
|
||||
{
|
||||
// 如果两次选中同一个,不做处理
|
||||
if (_selectedSubscription == value) return;
|
||||
|
||||
_selectedSubscription = value;
|
||||
OnPropertyChanged();
|
||||
|
||||
// ★★★ 核心逻辑:一旦选中项发生变化,就填充表单 ★★★
|
||||
if (_selectedSubscription != null)
|
||||
{
|
||||
FillForm(_selectedSubscription);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
// 3. 编写填充表单的辅助方法
|
||||
private void FillForm(SubscriptionDto dto)
|
||||
{
|
||||
// 这里我们将 DTO 的值“复制”到编辑属性中
|
||||
// 这样做的好处是:修改下方文本框时,不会立即改变列表里的显示,只有点击“保存”后才刷新
|
||||
EditAppId = dto.AppId;
|
||||
EditType = dto.Type; // 之前改成了 int,直接赋值即可
|
||||
EditFps = dto.DisplayFps; // 注意:后端返回可能是 targetFps,前端 DTO 映射已修复
|
||||
EditMemo = dto.Memo;
|
||||
|
||||
// 网络参数回显
|
||||
EditTargetIp = dto.TargetIp;
|
||||
EditTargetPort = dto.TargetPort;
|
||||
|
||||
// 触发一下 UI 状态刷新(比如网络参数的显隐)
|
||||
OnPropertyChanged(nameof(IsNetworkType));
|
||||
}
|
||||
}
|
||||
}
|
||||
Reference in New Issue
Block a user