using System.ComponentModel; using System.Windows; using System.Windows.Controls; using System.Windows.Controls.Primitives; using YY.Admin.ViewModels.RawMaterialEntry; namespace YY.Admin.Views.RawMaterialEntry; public partial class RawMaterialEntryOperationView : UserControl { private RawMaterialEntryOperationViewModel? _vm; private bool _initialized; public RawMaterialEntryOperationView() { InitializeComponent(); Loaded += OnLoaded; DataContextChanged += OnDataContextChanged; Unloaded += (_, _) => DetachVm(); } private void OnDataContextChanged(object sender, DependencyPropertyChangedEventArgs e) { DetachVm(); if (DataContext is RawMaterialEntryOperationViewModel vm) { _vm = vm; vm.PropertyChanged += OnVmPropertyChanged; vm.PrintPreviewHtmlReady += OnPrintPreviewHtmlReady; vm.StartPrintPreviewTimer(); } ApplySplitLayout(); } private void DetachVm() { if (_vm != null) { _vm.PropertyChanged -= OnVmPropertyChanged; _vm.PrintPreviewHtmlReady -= OnPrintPreviewHtmlReady; _vm.StopPrintPreviewTimer(); _vm = null; } } private void OnVmPropertyChanged(object? sender, PropertyChangedEventArgs e) { // null/空 表示“所有属性”通知(Prism/BindableBase 批量刷新时),需同步分割布局 if (!string.IsNullOrEmpty(e.PropertyName) && e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.IsRightPanelExpanded) && e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.ExpandedRightPanelWidth) && e.PropertyName is not nameof(RawMaterialEntryOperationViewModel.PrintPreviewZoomFactor)) return; 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); } } /// 按钮 Click 在 Command 之后执行,用于兜底刷新列宽(不重复切换状态)。 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(); ApplyPrintPreviewZoom(); if (DataContext is RawMaterialEntryOperationViewModel vm && !_initialized) { vm.InitializeForAdd(); _initialized = true; _ = vm.LoadTodayEntriesOnFirstShowAsync(); } } private void EnsureVmAttached() { if (_vm != null) return; if (DataContext is RawMaterialEntryOperationViewModel vm) { _vm = vm; vm.PropertyChanged += OnVmPropertyChanged; vm.PrintPreviewHtmlReady += OnPrintPreviewHtmlReady; vm.StartPrintPreviewTimer(); } } private async void OnPrintPreviewHtmlReady(object? sender, string html) { try { await PrintPreviewWebView.EnsureCoreWebView2Async(); ApplyPrintPreviewZoom(); PrintPreviewWebView.NavigateToString(html ?? string.Empty); } catch { /* WebView2 未就绪或宿主已释放时忽略 */ } } 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; } /// /// 根据 ViewModel 同步右侧栏与分割条:展开时使用持久化宽度;折叠时右栏与分割条占宽均为 0(完全隐藏)。 /// 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); } }