|
|
@@ -122,6 +122,7 @@ namespace ivf_tl_Operate.CustomUserControls
|
|
|
private readonly UIElement _existingMask; // 复用的 _mask(MainWindow),可空
|
|
|
private FrameworkElement _injectedMask; // 自注入遮罩(无 _mask 时)
|
|
|
private Grid _layer; // 承载键盘的浮层
|
|
|
+ private System.Windows.Controls.Primitives.Popup _popup; // G2-3:键盘改用顶层 Popup 托管(独立布局根,避免 Viewbox 内 MainGrid 不重测子树的坑)
|
|
|
private SoftKeyboard _keyboard;
|
|
|
private bool _disposed;
|
|
|
|
|
|
@@ -137,44 +138,62 @@ namespace ivf_tl_Operate.CustomUserControls
|
|
|
|
|
|
public void Show()
|
|
|
{
|
|
|
- if (_rootPanel == null) return;
|
|
|
+ bool maskMode = _mode == SoftKeyboardMode.Password;
|
|
|
|
|
|
- bool mask = _mode == SoftKeyboardMode.Password;
|
|
|
+ // 窗口尺寸(Popup 顶层、按屏幕像素布局,不随 Viewbox 缩放)。
|
|
|
+ double winW = _window != null && _window.ActualWidth > 0 ? _window.ActualWidth : 1920;
|
|
|
+ double winH = _window != null && _window.ActualHeight > 0 ? _window.ActualHeight : 1080;
|
|
|
+ double kbW = _mode == SoftKeyboardMode.Password ? System.Math.Min(960, winW * 0.62) : System.Math.Min(640, winW * 0.42);
|
|
|
+ // 高度:Password 全键盘=标题栏+5 行,Number=标题栏+4 行;上限给足,避免竖屏大屏下被压矮、底部行(清除/空格/确定)显示不全。
|
|
|
+ double kbH = _mode == SoftKeyboardMode.Password ? System.Math.Min(860, winH * 0.62) : System.Math.Min(680, winH * 0.55);
|
|
|
|
|
|
_keyboard = new SoftKeyboard
|
|
|
{
|
|
|
HorizontalAlignment = HorizontalAlignment.Center,
|
|
|
- VerticalAlignment = VerticalAlignment.Bottom,
|
|
|
- Margin = new Thickness(0, 0, 0, 60),
|
|
|
- MaxWidth = 1100,
|
|
|
- Width = _mode == SoftKeyboardMode.Password ? 1000 : 700
|
|
|
+ VerticalAlignment = VerticalAlignment.Center, // 居中:贴底会让最底行(确定)被屏幕底部裁掉,居中绝不被裁
|
|
|
+ Margin = new Thickness(0),
|
|
|
+ Width = kbW,
|
|
|
+ Height = kbH
|
|
|
};
|
|
|
- _keyboard.Reset(_mode, ReadTargetText(), mask);
|
|
|
+ _keyboard.Reset(_mode, ReadTargetText(), maskMode);
|
|
|
_keyboard.KeyInput += OnKeyInput;
|
|
|
_keyboard.RequestClose += OnRequestClose;
|
|
|
|
|
|
- // 浮层:自带一层点击可关闭的透明背景(点空白处=取消)。
|
|
|
- _layer = new Grid();
|
|
|
+ // 浮层:全窗口透明背景捕获点击(点空白处=取消)+ 键盘(底部居中)。
|
|
|
+ _layer = new Grid { Width = winW, Height = winH };
|
|
|
var bgCatcher = new Border { Background = Brushes.Transparent };
|
|
|
bgCatcher.MouseDown += (s, e) => OnRequestClose(false);
|
|
|
bgCatcher.TouchDown += (s, e) => OnRequestClose(false);
|
|
|
_layer.Children.Add(bgCatcher);
|
|
|
_layer.Children.Add(_keyboard);
|
|
|
|
|
|
- // 背景压暗:优先复用窗口现成 _mask(与 M2-05 标定弹窗一致);否则注入一层。
|
|
|
+ // 背景压暗:优先复用窗口现成 _mask(与 M2-05 标定弹窗一致);否则在根面板注入一层。
|
|
|
if (_existingMask is UIElement mk)
|
|
|
{
|
|
|
mk.Visibility = Visibility.Visible;
|
|
|
}
|
|
|
- else
|
|
|
+ else if (_rootPanel != null)
|
|
|
{
|
|
|
_injectedMask = new Grid { Background = new SolidColorBrush(Color.FromArgb(204, 0, 0, 0)) };
|
|
|
_rootPanel.Children.Add(_injectedMask);
|
|
|
+ Panel.SetZIndex(_injectedMask, int.MaxValue - 1);
|
|
|
}
|
|
|
|
|
|
- _rootPanel.Children.Add(_layer);
|
|
|
- Panel.SetZIndex(_layer, int.MaxValue);
|
|
|
- if (_injectedMask != null) Panel.SetZIndex(_injectedMask, int.MaxValue - 1);
|
|
|
+ // 键盘放进顶层 Popup —— 独立布局根,必被测量/渲染;规避"MainGrid 固定尺寸且在 Viewbox 内、
|
|
|
+ // 动态新增子树布局失效不被父级重新测量"的坑(实测会导致键盘 0×0 不可见)。
|
|
|
+ _popup = new System.Windows.Controls.Primitives.Popup
|
|
|
+ {
|
|
|
+ PlacementTarget = _window,
|
|
|
+ Placement = System.Windows.Controls.Primitives.PlacementMode.Relative,
|
|
|
+ HorizontalOffset = 0,
|
|
|
+ VerticalOffset = 0,
|
|
|
+ Width = winW,
|
|
|
+ Height = winH,
|
|
|
+ AllowsTransparency = true,
|
|
|
+ StaysOpen = true,
|
|
|
+ Child = _layer
|
|
|
+ };
|
|
|
+ _popup.IsOpen = true;
|
|
|
}
|
|
|
|
|
|
private void OnKeyInput(string text) => WriteTargetText(text);
|
|
|
@@ -191,7 +210,12 @@ namespace ivf_tl_Operate.CustomUserControls
|
|
|
_keyboard.KeyInput -= OnKeyInput;
|
|
|
_keyboard.RequestClose -= OnRequestClose;
|
|
|
}
|
|
|
- if (_layer != null) _rootPanel?.Children.Remove(_layer);
|
|
|
+ if (_popup != null)
|
|
|
+ {
|
|
|
+ _popup.IsOpen = false;
|
|
|
+ _popup.Child = null;
|
|
|
+ _popup = null;
|
|
|
+ }
|
|
|
if (_injectedMask != null) _rootPanel?.Children.Remove(_injectedMask);
|
|
|
// 复用的 _mask:仅当我们点亮过才隐藏(弹窗自身可能也用它——这里保守隐藏,
|
|
|
// 因为同一时刻不会有标定弹窗与键盘并存:键盘弹出时页面处于输入态)。
|