2026-05-11 14:32:44 +08:00
|
|
|
|
using System.ComponentModel;
|
2026-05-09 18:25:34 +08:00
|
|
|
|
using System.Windows;
|
|
|
|
|
|
using System.Windows.Controls;
|
2026-05-11 14:32:44 +08:00
|
|
|
|
using System.Windows.Controls.Primitives;
|
2026-05-15 17:30:30 +08:00
|
|
|
|
using YY.Admin.Helper;
|
2026-05-09 18:25:34 +08:00
|
|
|
|
using YY.Admin.ViewModels.RawMaterialEntry;
|
|
|
|
|
|
|
|
|
|
|
|
namespace YY.Admin.Views.RawMaterialEntry;
|
|
|
|
|
|
|
|
|
|
|
|
public partial class RawMaterialEntryOperationView : UserControl
|
|
|
|
|
|
{
|
2026-05-11 14:32:44 +08:00
|
|
|
|
private RawMaterialEntryOperationViewModel? _vm;
|
2026-05-09 18:25:34 +08:00
|
|
|
|
private bool _initialized;
|
|
|
|
|
|
|
|
|
|
|
|
public RawMaterialEntryOperationView()
|
|
|
|
|
|
{
|
|
|
|
|
|
InitializeComponent();
|
2026-05-15 17:30:30 +08:00
|
|
|
|
PrintPreviewWebView.CreationProperties = WebView2UserDataFolder.CreateCreationProperties("RawMaterialEntryPreview");
|
2026-05-09 18:25:34 +08:00
|
|
|
|
Loaded += OnLoaded;
|
2026-05-11 14:32:44 +08:00
|
|
|
|
DataContextChanged += OnDataContextChanged;
|
|
|
|
|
|
Unloaded += (_, _) => DetachVm();
|
2026-05-09 18:25:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-11 14:32:44 +08:00
|
|
|
|
private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e)
|
2026-05-09 18:25:34 +08:00
|
|
|
|
{
|
2026-05-11 14:32:44 +08:00
|
|
|
|
DetachVm();
|
|
|
|
|
|
if (DataContext is RawMaterialEntryOperationViewModel vm)
|
2026-05-09 18:25:34 +08:00
|
|
|
|
{
|
2026-05-11 14:32:44 +08:00
|
|
|
|
_vm = vm;
|
|
|
|
|
|
vm.PropertyChanged += OnVmPropertyChanged;
|
2026-05-14 10:43:51 +08:00
|
|
|
|
vm.PrintPreviewHtmlReady += OnPrintPreviewHtmlReady;
|
|
|
|
|
|
vm.StartPrintPreviewTimer();
|
2026-05-11 14:32:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
ApplySplitLayout();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void DetachVm()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_vm != null)
|
|
|
|
|
|
{
|
|
|
|
|
|
_vm.PropertyChanged -= OnVmPropertyChanged;
|
2026-05-14 10:43:51 +08:00
|
|
|
|
_vm.PrintPreviewHtmlReady -= OnPrintPreviewHtmlReady;
|
|
|
|
|
|
_vm.StopPrintPreviewTimer();
|
2026-05-11 14:32:44 +08:00
|
|
|
|
_vm = null;
|
2026-05-09 18:25:34 +08:00
|
|
|
|
}
|
2026-05-11 14:32:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void OnVmPropertyChanged(object? sender, PropertyChangedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// null/空 表示“所有属性”通知(Prism/BindableBase 批量刷新时),需同步分割布局
|
|
|
|
|
|
if (!string.IsNullOrEmpty(e.PropertyName)
|
|
|
|
|
|
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.IsRightPanelExpanded)
|
2026-05-14 11:25:17 +08:00
|
|
|
|
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.ExpandedRightPanelWidth)
|
|
|
|
|
|
&& e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.PrintPreviewZoomFactor))
|
2026-05-11 14:32:44 +08:00
|
|
|
|
return;
|
|
|
|
|
|
|
2026-05-14 11:25:17 +08:00
|
|
|
|
if (string.IsNullOrEmpty(e.PropertyName)
|
|
|
|
|
|
|| e.PropertyName is nameof(RawMaterialEntryOperationViewModel.IsRightPanelExpanded)
|
|
|
|
|
|
|| e.PropertyName is nameof(RawMaterialEntryOperationViewModel.ExpandedRightPanelWidth))
|
|
|
|
|
|
{
|
|
|
|
|
|
_ = Dispatcher.InvokeAsync(ApplySplitLayout);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
if (string.IsNullOrEmpty(e.PropertyName)
|
|
|
|
|
|
|| e.PropertyName is nameof(RawMaterialEntryOperationViewModel.PrintPreviewZoomFactor))
|
|
|
|
|
|
{
|
|
|
|
|
|
_ = Dispatcher.InvokeAsync(ApplyPrintPreviewZoom);
|
|
|
|
|
|
}
|
2026-05-11 14:32:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
/// <summary>按钮 Click 在 Command 之后执行,用于兜底刷新列宽(不重复切换状态)。</summary>
|
|
|
|
|
|
private void ToggleTodayPanelButton_OnClick(object sender, RoutedEventArgs e) => ApplySplitLayout();
|
|
|
|
|
|
|
|
|
|
|
|
private void OnLoaded(object sender, RoutedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
// 兜底:XAML 解析 prism:AutoWireViewModel 时设置 DataContext 早于构造函数订阅 DataContextChanged,
|
|
|
|
|
|
// 首次进入页面 OnDataContextChanged 会错过回调,导致 _vm 为 null、PropertyChanged 未挂接,
|
|
|
|
|
|
// 表现为「首次点击展开/收起按钮不生效」。这里在 Loaded 时补一次订阅。
|
|
|
|
|
|
EnsureVmAttached();
|
|
|
|
|
|
|
|
|
|
|
|
ApplySplitLayout();
|
2026-05-14 11:25:17 +08:00
|
|
|
|
ApplyPrintPreviewZoom();
|
2026-05-09 18:25:34 +08:00
|
|
|
|
|
2026-05-11 14:32:44 +08:00
|
|
|
|
if (DataContext is RawMaterialEntryOperationViewModel vm && !_initialized)
|
2026-05-09 18:25:34 +08:00
|
|
|
|
{
|
|
|
|
|
|
vm.InitializeForAdd();
|
|
|
|
|
|
_initialized = true;
|
2026-05-11 14:32:44 +08:00
|
|
|
|
_ = vm.LoadTodayEntriesOnFirstShowAsync();
|
2026-05-09 18:25:34 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
2026-05-11 14:32:44 +08:00
|
|
|
|
|
|
|
|
|
|
private void EnsureVmAttached()
|
|
|
|
|
|
{
|
|
|
|
|
|
if (_vm != null) return;
|
|
|
|
|
|
if (DataContext is RawMaterialEntryOperationViewModel vm)
|
|
|
|
|
|
{
|
|
|
|
|
|
_vm = vm;
|
|
|
|
|
|
vm.PropertyChanged += OnVmPropertyChanged;
|
2026-05-14 10:43:51 +08:00
|
|
|
|
vm.PrintPreviewHtmlReady += OnPrintPreviewHtmlReady;
|
|
|
|
|
|
vm.StartPrintPreviewTimer();
|
|
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private async void OnPrintPreviewHtmlReady(object? sender, string html)
|
|
|
|
|
|
{
|
|
|
|
|
|
try
|
|
|
|
|
|
{
|
|
|
|
|
|
await PrintPreviewWebView.EnsureCoreWebView2Async();
|
2026-05-14 11:25:17 +08:00
|
|
|
|
ApplyPrintPreviewZoom();
|
2026-05-14 10:43:51 +08:00
|
|
|
|
PrintPreviewWebView.NavigateToString(html ?? string.Empty);
|
|
|
|
|
|
}
|
|
|
|
|
|
catch
|
|
|
|
|
|
{
|
|
|
|
|
|
/* WebView2 未就绪或宿主已释放时忽略 */
|
2026-05-11 14:32:44 +08:00
|
|
|
|
}
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-14 11:25:17 +08:00
|
|
|
|
private void ApplyPrintPreviewZoom()
|
|
|
|
|
|
{
|
|
|
|
|
|
var vm = _vm ?? DataContext as RawMaterialEntryOperationViewModel;
|
|
|
|
|
|
if (vm == null) return;
|
|
|
|
|
|
if (PrintPreviewWebView?.CoreWebView2 == null) return;
|
|
|
|
|
|
// 实时预览已关闭 HTML 内部 fitPage,自定义缩放直接映射到 WebView2 即可(+ 放大,- 缩小)。
|
|
|
|
|
|
PrintPreviewWebView.ZoomFactor = vm.PrintPreviewZoomFactor;
|
|
|
|
|
|
}
|
|
|
|
|
|
|
2026-05-11 14:32:44 +08:00
|
|
|
|
/// <summary>
|
|
|
|
|
|
/// 根据 ViewModel 同步右侧栏与分割条:展开时使用持久化宽度;折叠时右栏与分割条占宽均为 0(完全隐藏)。
|
|
|
|
|
|
/// </summary>
|
|
|
|
|
|
private void ApplySplitLayout()
|
|
|
|
|
|
{
|
|
|
|
|
|
var vm = _vm ?? DataContext as RawMaterialEntryOperationViewModel;
|
|
|
|
|
|
if (vm == null) return;
|
|
|
|
|
|
|
|
|
|
|
|
if (vm.IsRightPanelExpanded)
|
|
|
|
|
|
{
|
|
|
|
|
|
RightPaneSplitter.Visibility = Visibility.Visible;
|
|
|
|
|
|
SplitterCol.Width = new GridLength(4);
|
|
|
|
|
|
RightPaneCol.Width = new GridLength(vm.ExpandedRightPanelWidth);
|
|
|
|
|
|
}
|
|
|
|
|
|
else
|
|
|
|
|
|
{
|
|
|
|
|
|
RightPaneSplitter.Visibility = Visibility.Collapsed;
|
|
|
|
|
|
SplitterCol.Width = new GridLength(0);
|
|
|
|
|
|
RightPaneCol.Width = new GridLength(0);
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
MainSplitRoot.InvalidateMeasure();
|
|
|
|
|
|
MainSplitRoot.UpdateLayout();
|
|
|
|
|
|
}
|
|
|
|
|
|
|
|
|
|
|
|
private void RightPaneSplitter_OnDragCompleted(object sender, DragCompletedEventArgs e)
|
|
|
|
|
|
{
|
|
|
|
|
|
var vm = _vm ?? DataContext as RawMaterialEntryOperationViewModel;
|
|
|
|
|
|
if (vm == null || !vm.IsRightPanelExpanded || e.Canceled) return;
|
|
|
|
|
|
|
|
|
|
|
|
var w = RightPaneCol.ActualWidth;
|
|
|
|
|
|
if (w >= 120)
|
|
|
|
|
|
vm.CommitRightPanelWidthFromView(w);
|
|
|
|
|
|
}
|
2026-05-09 18:25:34 +08:00
|
|
|
|
}
|