using System.Drawing; namespace System.Windows.Forms { public class TabPage : ContainerControl { protected new System.Windows.Controls.TabItem control { get; } public override string Text { get => control.Header?.ToString(); set => control.Header = value; } public bool UseVisualStyleBackColor { get; set; } // WPF TabItem control is just a "tab" (not a container for its child controls), so its location/size should not be changed. protected override void SetControlLeft(int value) { } protected override void SetControlTop(int value) { } protected override void SetControlWidth(int value) { } protected override void SetControlHeight(int value) { } // return actual bounding rectangle to make layout engine working (case: FR QueryBuilder in pmV2) public override Rectangle DisplayRectangle => container.ActualWidth == 0 ? base.DisplayRectangle : new Rectangle(0, 0, (int)(container.ActualWidth * DpiScale), (int)(container.ActualHeight * DpiScale)); private void EnumControls(Control control, Action action) { action(control); foreach (Control c in control.Controls) EnumControls(c, action); } public TabPage() { control = new(); SetContentControl(control); control.HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch; control.VerticalAlignment = System.Windows.VerticalAlignment.Stretch; // the actual container for tab's child controls is this.container so we need to watch its size control.SizeChanged -= Size_Changed; container.SizeChanged += (s, e) => { container.Dispatcher.InvokeAsync(() => { // fix issues with pmV2: refresh controls when tab page becomes active and its dpi is changed (case: FR chart editor) EnumControls(this, c => c.Refresh()); }); Size_Changed(s, e); }; } } }