diff --git a/src/Eto.WinForms/Win32.cs b/src/Eto.WinForms/Win32.cs index 7f6d59428f..d88674c224 100644 --- a/src/Eto.WinForms/Win32.cs +++ b/src/Eto.WinForms/Win32.cs @@ -3,6 +3,8 @@ using System.Windows.Forms; using System.Text; using System.Diagnostics; +using System.Collections.Generic; +using System.Linq; namespace Eto { @@ -175,7 +177,7 @@ public enum WM NCCREATE = 0x0081, NCLBUTTONDOWN = 0x00A1 } - + public enum HT { CAPTION = 0x2 @@ -435,10 +437,46 @@ public static bool ApplicationIsActivated() [DllImport("user32.dll", CharSet = CharSet.Auto, ExactSpelling = true)] - private static extern IntPtr GetForegroundWindow(); + public static extern IntPtr GetForegroundWindow(); [DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)] private static extern int GetWindowThreadProcessId(IntPtr handle, out int processId); + [DllImport("user32.dll")] + [return: MarshalAs(UnmanagedType.Bool)] + public static extern bool GetGUIThreadInfo(uint idThread, ref GUITHREADINFO lpgui); + + [StructLayout(LayoutKind.Sequential)] + public struct GUITHREADINFO + { + public int cbSize; + public uint flags; + public IntPtr hwndActive; + public IntPtr hwndFocus; + public IntPtr hwndCapture; + public IntPtr hwndMenuOwner; + public IntPtr hwndMoveSize; + public IntPtr hwndCaret; + public RECT rcCaret; + } + + [DllImport("kernel32.dll")] + static extern uint GetCurrentThreadId(); + + public static bool GetInfo(out GUITHREADINFO lpgui, uint? threadId = null) + { + lpgui = new GUITHREADINFO(); + lpgui.cbSize = Marshal.SizeOf(lpgui); + + return GetGUIThreadInfo(threadId ?? GetCurrentThreadId(), ref lpgui); + } + + public static IntPtr GetThreadFocusWindow(uint? threadId = null) + { + if (!GetInfo(out var info, threadId)) + return IntPtr.Zero; + + return info.hwndFocus; + } } } diff --git a/src/Eto.Wpf/Forms/ApplicationHandler.cs b/src/Eto.Wpf/Forms/ApplicationHandler.cs index 4644270123..f6b7ac07fe 100755 --- a/src/Eto.Wpf/Forms/ApplicationHandler.cs +++ b/src/Eto.Wpf/Forms/ApplicationHandler.cs @@ -125,9 +125,8 @@ void OnCurrentDomainUnhandledException(object sender, System.UnhandledExceptionE void HandleStartup(object sender, sw.StartupEventArgs e) { - IsActive = true; IsStarted = true; - _isActive = Win32.ApplicationIsActivated(); + IsActive = Win32.ApplicationIsActivated(); Control.Activated += (sender2, e2) => IsActive = true; Control.Deactivated += (sender2, e2) => IsActive = false; if (delayShownWindows != null) diff --git a/src/Eto.Wpf/Forms/FloatingFormHandler.cs b/src/Eto.Wpf/Forms/FloatingFormHandler.cs index b2d6969849..16be37fe71 100755 --- a/src/Eto.Wpf/Forms/FloatingFormHandler.cs +++ b/src/Eto.Wpf/Forms/FloatingFormHandler.cs @@ -1,10 +1,16 @@ using System; +using System.Windows; +using System.Windows.Interop; using Eto.Forms; namespace Eto.Wpf.Forms { public class FloatingFormHandler : FormHandler, FloatingForm.IHandler { + static readonly object Visible_Key = new object(); + + bool _wasActive; + protected override void Initialize() { base.Initialize(); @@ -31,19 +37,40 @@ public override void OnUnLoad(EventArgs e) private void Application_IsActiveChanged(object sender, EventArgs e) { - base.Visible = ApplicationHandler.Instance.IsActive && _visible; + SetVisibility(); } - - bool _visible = true; - + public override bool Visible { - get => _visible; + get => Widget.Properties.Get(Visible_Key, true); set { - _visible = value; - if (ApplicationHandler.Instance.IsActive) - base.Visible = value; + if (Widget.Properties.TrySet(Visible_Key, value, true)) + SetVisibility(); + } + } + + void SetVisibility() + { + var currentlyVisible = base.Visible; + var isVisible = ApplicationHandler.Instance.IsActive && Visible; + if (isVisible == currentlyVisible) + return; + + if (!isVisible) + { + if (currentlyVisible) + { + _wasActive = Win32.GetThreadFocusWindow() == NativeHandle; + } + base.Visible = isVisible; + } + else + { + var oldShowActivated = Control.ShowActivated; + Control.ShowActivated = _wasActive; + base.Visible = isVisible; + Control.ShowActivated = oldShowActivated; } } } diff --git a/src/Eto.Wpf/Forms/FormHandler.cs b/src/Eto.Wpf/Forms/FormHandler.cs index 9d7a2f9c60..81e122b79b 100644 --- a/src/Eto.Wpf/Forms/FormHandler.cs +++ b/src/Eto.Wpf/Forms/FormHandler.cs @@ -48,7 +48,9 @@ public virtual void Show() { Control.WindowStartupLocation = sw.WindowStartupLocation.Manual; if (ApplicationHandler.Instance.IsStarted) + { Control.Show(); + } else ApplicationHandler.Instance.DelayShownWindows.Add(Control); WpfFrameworkElementHelper.ShouldCaptureMouse = false; @@ -65,9 +67,8 @@ public bool CanFocus get { return Control.Focusable; } set { - SetStyle(Win32.WS_EX.NOACTIVATE, !value); - SetStyle(Win32.WS.CHILD, !value); Control.Focusable = value; + SetStyleEx(Win32.WS_EX.NOACTIVATE, !value); } } } diff --git a/src/Eto.Wpf/Forms/WpfFrameworkElement.cs b/src/Eto.Wpf/Forms/WpfFrameworkElement.cs index e177552e47..faa2c597ae 100755 --- a/src/Eto.Wpf/Forms/WpfFrameworkElement.cs +++ b/src/Eto.Wpf/Forms/WpfFrameworkElement.cs @@ -439,51 +439,17 @@ public override void AttachEvent(string id) HandleEvent(Eto.Forms.Control.MouseDownEvent); break; case Eto.Forms.Control.MouseEnterEvent: - ContainerControl.MouseEnter += (sender, e) => - { - if (isMouseOver != Control.IsMouseOver) - { - var args = e.ToEto(Control); - Callback.OnMouseEnter(Widget, args); - e.Handled = args.Handled; - isMouseOver = Control.IsMouseOver; - } - }; + ContainerControl.MouseEnter += HandleMouseEnter; break; case Eto.Forms.Control.MouseLeaveEvent: HandleEvent(Eto.Forms.Control.MouseEnterEvent); - ContainerControl.MouseLeave += (sender, e) => - { - if (isMouseOver != Control.IsMouseOver) - { - var args = e.ToEto(Control); - Callback.OnMouseLeave(Widget, args); - e.Handled = args.Handled; - isMouseOver = Control.IsMouseOver; - } - }; + ContainerControl.MouseLeave += HandleMouseLeave; break; case Eto.Forms.Control.MouseWheelEvent: - ContainerControl.PreviewMouseWheel += (sender, e) => - { - var args = e.ToEto(Control); - Callback.OnMouseWheel(Widget, args); - e.Handled = args.Handled; - }; + ContainerControl.PreviewMouseWheel += HandlePreviewMouseWheel; break; case Eto.Forms.Control.SizeChangedEvent: - ContainerControl.SizeChanged += (sender, e) => - { - // - var size = e.NewSize.ToEtoSize(); - var prev = e.PreviousSize.ToEtoSize(); - if (size != prev) // WPF calls this event even if it hasn't changed - { - newSize = size; // so we can report this back in Control.Size - Callback.OnSizeChanged(Widget, EventArgs.Empty); - newSize = null; - } - }; + ContainerControl.SizeChanged += HandleSizeChanged; break; case Eto.Forms.Control.KeyDownEvent: if (UseKeyPreview) @@ -504,25 +470,10 @@ public override void AttachEvent(string id) Control.KeyUp += HandleKeyUp; break; case Eto.Forms.Control.ShownEvent: - ContainerControl.IsVisibleChanged += (sender, e) => - { - if ((bool)e.NewValue) - { - Callback.OnShown(Widget, EventArgs.Empty); - } - }; + ContainerControl.IsVisibleChanged += HandleIsVisibleChanged; break; case Eto.Forms.Control.GotFocusEvent: - Control.IsKeyboardFocusWithinChanged += (sender, e) => - { - // sometimes this gets called after disposed? Happens with designer in VS 2017 - if (Control == null) - return; - if (HasFocus) - Callback.OnGotFocus(Widget, EventArgs.Empty); - else - Callback.OnLostFocus(Widget, EventArgs.Empty); - }; + Control.IsKeyboardFocusWithinChanged += HandleIsKeyboardFocusWithinChanged; break; case Eto.Forms.Control.LostFocusEvent: HandleEvent(Eto.Forms.Control.GotFocusEvent); @@ -551,6 +502,70 @@ public override void AttachEvent(string id) } } + private void HandleIsKeyboardFocusWithinChanged(object sender, sw.DependencyPropertyChangedEventArgs e) + { + // sometimes this gets called after disposed? Happens with designer in VS 2017 + if (Control == null) + return; + if (HasFocus) + Callback.OnGotFocus(Widget, EventArgs.Empty); + else + Callback.OnLostFocus(Widget, EventArgs.Empty); + } + + private void HandlePreviewMouseWheel(object sender, swi.MouseWheelEventArgs e) + { + if (Control == null) + return; + var args = e.ToEto(Control); + Callback.OnMouseWheel(Widget, args); + e.Handled = args.Handled; + } + + private void HandleIsVisibleChanged(object sender, sw.DependencyPropertyChangedEventArgs e) + { + if ((bool)e.NewValue) + { + Callback.OnShown(Widget, EventArgs.Empty); + } + } + + private void HandleSizeChanged(object sender, sw.SizeChangedEventArgs e) + { + if (Control == null) + return; + var size = e.NewSize.ToEtoSize(); + var prev = e.PreviousSize.ToEtoSize(); + if (size != prev) // WPF calls this event even if it hasn't changed + { + newSize = size; // so we can report this back in Control.Size + Callback.OnSizeChanged(Widget, EventArgs.Empty); + newSize = null; + } + } + + private void HandleMouseLeave(object sender, swi.MouseEventArgs e) + { + if (Control == null || isMouseOver == Control.IsMouseOver) + return; + + var args = e.ToEto(Control); + Callback.OnMouseLeave(Widget, args); + e.Handled = args.Handled; + isMouseOver = Control.IsMouseOver; + } + + private void HandleMouseEnter(object sender, swi.MouseEventArgs e) + { + if (Control == null || isMouseOver == Control.IsMouseOver) + return; + + var args = e.ToEto(Control); + Callback.OnMouseEnter(Widget, args); + e.Handled = args.Handled; + isMouseOver = Control.IsMouseOver; + } + private void Control_DragDrop(object sender, sw.DragEventArgs e) { var args = GetDragEventArgs(e, null); @@ -565,6 +580,8 @@ private void Control_DragOver(object sender, sw.DragEventArgs e) private void Control_IsEnabledChanged(object sender, sw.DependencyPropertyChangedEventArgs e) { + if (Control == null) + return; Callback.OnEnabledChanged(Widget, EventArgs.Empty); } @@ -696,8 +713,8 @@ protected virtual void HandleDragOver(sw.DragEventArgs e, DragEventArgs args) } protected virtual DragEventArgs GetDragEventArgs(sw.DragEventArgs data, object controlObject) - { - var dragData = (data.Data as sw.DataObject).ToEto(); + { + var dragData = (data.Data as sw.DataObject).ToEto(); Control source = WpfFrameworkElement.DragSourceControl; @@ -717,9 +734,9 @@ protected virtual DragEventArgs GetDragEventArgs(sw.DragEventArgs data, object c if (data.KeyStates.HasFlag(sw.DragDropKeyStates.MiddleMouseButton)) buttons |= MouseButtons.Middle; return new WpfDragEventArgs(source, dragData, data.AllowedEffects.ToEto(), location, modifiers, buttons, controlObject); - } + } - void HandleTextInput(object sender, swi.TextCompositionEventArgs e) + void HandleTextInput(object sender, swi.TextCompositionEventArgs e) { var tiargs = new TextInputEventArgs(e.Text); Callback.OnTextInput(Widget, tiargs); @@ -812,7 +829,7 @@ protected virtual void HandleMouseDown(object sender, swi.MouseButtonEventArgs e } } - protected override void Initialize() + protected override void Initialize() { base.Initialize(); Control.Tag = this; @@ -934,7 +951,7 @@ public virtual int TabIndex public virtual IEnumerable VisualControls => Enumerable.Empty(); public void DoDragDrop(DataObject data, DragEffects allowedAction, Image image, PointF offset) - { + { WpfFrameworkElementHelper.ShouldCaptureMouse = false; var dataObject = data.ToWpf(); diff --git a/src/Eto.Wpf/Forms/WpfWindow.cs b/src/Eto.Wpf/Forms/WpfWindow.cs index 171221091a..854d856e23 100644 --- a/src/Eto.Wpf/Forms/WpfWindow.cs +++ b/src/Eto.Wpf/Forms/WpfWindow.cs @@ -59,11 +59,21 @@ public abstract class WpfWindow : WpfPanel false; + sw.Interop.WindowInteropHelper windowInterop; + public override IntPtr NativeHandle { - get { return new System.Windows.Interop.WindowInteropHelper(Control).EnsureHandle(); } + get + { + if (windowInterop == null) + { + windowInterop = new sw.Interop.WindowInteropHelper(Control); + windowInterop.EnsureHandle(); + } + return windowInterop.Handle; + } } - + public static bool EnablePerMonitorDpiSupport { get; set; } = true; public swc.DockPanel ContentPanel { get { return content; } } @@ -487,40 +497,30 @@ public virtual bool Minimizable } } - internal void SetStyle(Win32.WS_EX style, bool value) + internal void SetStyleEx(Win32.WS_EX style, bool value) { - var styleInt = Win32.GetWindowLong(WindowHandle, Win32.GWL.EXSTYLE); - if (value) - styleInt |= (uint)style; - else - styleInt &= (uint)~style; - - Win32.SetWindowLong(WindowHandle, Win32.GWL.EXSTYLE, styleInt); + SetStyleEx(value ? style : 0, value ? 0 : style); + } + + internal void SetStyleEx(Win32.WS_EX styleAdd, Win32.WS_EX styleRemove = 0) + { + var styleInt = Win32.GetWindowLong(NativeHandle, Win32.GWL.EXSTYLE); + styleInt |= (uint)styleAdd; + styleInt &= (uint)~styleRemove; + Win32.SetWindowLong(NativeHandle, Win32.GWL.EXSTYLE, styleInt); } internal void SetStyle(Win32.WS style, bool value) { - var styleInt = Win32.GetWindowLong(WindowHandle, Win32.GWL.STYLE); - if (value) - styleInt |= (uint)style; - else - styleInt &= (uint)~style; - - Win32.SetWindowLong(WindowHandle, Win32.GWL.STYLE, styleInt); + SetStyle(value ? style : 0, value ? 0 : style); } - sw.Interop.WindowInteropHelper windowInterop; - IntPtr WindowHandle + internal void SetStyle(Win32.WS styleAdd, Win32.WS styleRemove = 0) { - get - { - if (windowInterop == null) - { - windowInterop = new sw.Interop.WindowInteropHelper(Control); - windowInterop.EnsureHandle(); - } - return windowInterop.Handle; - } + var styleInt = Win32.GetWindowLong(NativeHandle, Win32.GWL.STYLE); + styleInt |= (uint)styleAdd; + styleInt &= (uint)~styleRemove; + Win32.SetWindowLong(NativeHandle, Win32.GWL.STYLE, styleInt); } protected virtual void SetResizeMode() @@ -599,7 +599,7 @@ public override Size Size { get { - var handle = WindowHandle; + var handle = NativeHandle; if (handle != IntPtr.Zero && Control.IsLoaded) { // WPF doesn't always report the correct size when maximized @@ -646,7 +646,7 @@ System.Windows.Forms.Screen SwfScreen { get { - var handle = WindowHandle; + var handle = NativeHandle; if (handle == IntPtr.Zero) return System.Windows.Forms.Screen.PrimaryScreen; return System.Windows.Forms.Screen.FromHandle(handle); @@ -661,7 +661,7 @@ System.Windows.Forms.Screen SwfScreen { if (initialLocation != null) return initialLocation.Value; - var handle = WindowHandle; + var handle = NativeHandle; if (handle != IntPtr.Zero) { Point? location = null; @@ -698,7 +698,7 @@ System.Windows.Forms.Screen SwfScreen if (IsAttached) throw new NotSupportedException(); - if (WindowHandle == IntPtr.Zero) + if (NativeHandle == IntPtr.Zero) { // set location when the source is initialized and we have a Win32 handle to move about // using Left/Top doesn't work (properly) in a per-monitor dpi environment. @@ -727,11 +727,11 @@ void Control_SourceInitialized(object sender, EventArgs e) void SetLocation(PointF location) { - var handle = WindowHandle; + var handle = NativeHandle; var loc = location.LogicalToScreen(); var oldDpiAwareness = Win32.SetThreadDpiAwarenessContextSafe(Win32.DPI_AWARENESS_CONTEXT.PER_MONITOR_AWARE_v2); - Win32.SetWindowPos(WindowHandle, IntPtr.Zero, loc.X, loc.Y, 0, 0, Win32.SWP.NOSIZE | Win32.SWP.NOACTIVATE); + Win32.SetWindowPos(NativeHandle, IntPtr.Zero, loc.X, loc.Y, 0, 0, Win32.SWP.NOSIZE | Win32.SWP.NOACTIVATE); if (oldDpiAwareness != Win32.DPI_AWARENESS_CONTEXT.NONE) Win32.SetThreadDpiAwarenessContextSafe(oldDpiAwareness); } @@ -840,7 +840,7 @@ public void BringToFront() if (!Control.Focusable) { - var hWnd = WindowHandle; + var hWnd = NativeHandle; if (hWnd != IntPtr.Zero) Win32.SetWindowPos(hWnd, Win32.HWND_TOP, 0, 0, 0, 0, Win32.SWP.NOSIZE | Win32.SWP.NOMOVE); } @@ -852,7 +852,7 @@ public void SendToBack() { if (Topmost) return; - var hWnd = WindowHandle; + var hWnd = NativeHandle; if (hWnd != IntPtr.Zero) Win32.SetWindowPos(hWnd, Win32.HWND_BOTTOM, 0, 0, 0, 0, Win32.SWP.NOSIZE | Win32.SWP.NOMOVE | Win32.SWP.NOACTIVATE); var window = sw.Application.Current.Windows.OfType().FirstOrDefault(r => r != Control); @@ -914,14 +914,26 @@ public float LogicalPixelSize return scale; } } - + protected override void Dispose(bool disposing) { // close the window when disposing from Eto explicitly if (disposing) Close(); - + base.Dispose(disposing); } + + public override bool Visible + { + get => Control.IsVisible; + set + { + if (value) + Control.Show(); + else + Control.Hide(); + } + } } } diff --git a/test/Eto.Test/Sections/Behaviors/WindowsSection.cs b/test/Eto.Test/Sections/Behaviors/WindowsSection.cs index 83e9824567..91ced8c7f2 100644 --- a/test/Eto.Test/Sections/Behaviors/WindowsSection.cs +++ b/test/Eto.Test/Sections/Behaviors/WindowsSection.cs @@ -16,7 +16,7 @@ public class WindowsSection : Panel, INotifyPropertyChanged RadioButtonList typeRadio; CheckBox resizableCheckBox; CheckBox maximizableCheckBox; - ResettableCheckBox minimizableCheckBox; + CheckBox minimizableCheckBox; CheckBox movableByWindowBackgroundCheckBox; CheckBox showInTaskBarCheckBox; CheckBox topMostCheckBox; @@ -27,7 +27,7 @@ public class WindowsSection : Panel, INotifyPropertyChanged CheckBox createMenuBar; EnumCheckBoxList systemMenuItems; EnumDropDown dialogDisplayModeDropDown; - + static readonly object CancelCloseKey = new object(); public bool CancelClose { @@ -58,6 +58,23 @@ public WindowsSection() layout.Add(null); Content = layout; + + DataContext = settings = new SettingsWindow(); + } + + SettingsWindow settings; + + class SettingsWindow + { + public bool ThreeState => true; // enable three state for these settings + public bool? Resizable { get; set; } + public bool? CanFocus { get; set; } + public bool? Minimizable { get; set;} + public bool? Maximizable { get; set;} + public bool? MovableByWindowBackground { get; set; } + public bool? ShowInTaskbar { get; set;} + public bool? ShowActivated { get; set; } + public bool? Topmost { get; set; } } protected override void OnUnLoad(EventArgs e) @@ -137,38 +154,10 @@ Control CreateTypeControls() Items = { typeRadio, setOwnerCheckBox } }; } - - class ResettableCheckBox : CheckBox - { - bool wasNull; - public ResettableCheckBox() - { - ThreeState = true; - Checked = null; - } - - protected override void OnDataContextChanged(EventArgs e) - { - if (DataContext != null) - { - wasNull = Checked == null; - } - base.OnDataContextChanged(e); - if (DataContext != null && Checked != null) - { - ThreeState = false; - } - else if (DataContext == null) - { - ThreeState = true; - if (wasNull) - Checked = null; - } - } - } - + Control WindowStyle() { + var enableStyle = new CheckBox { Checked = false }; styleCombo = new EnumRadioButtonList { SelectedValue = Forms.WindowStyle.Default @@ -178,7 +167,9 @@ Control WindowStyle() if (child != null) child.WindowStyle = styleCombo.SelectedValue; }; - return styleCombo; + + styleCombo.Bind(c => c.Enabled, enableStyle, c => c.Checked); + return new TableLayout(new TableRow(enableStyle, styleCombo)); } Control DisplayModeDropDown() @@ -209,63 +200,72 @@ Control WindowState() Control Resizable() { - resizableCheckBox = new ResettableCheckBox { Text = "Resizable" }; + resizableCheckBox = new CheckBox { Text = "Resizable" }; + resizableCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); resizableCheckBox.CheckedBinding.BindDataContext((Window w) => w.Resizable); return resizableCheckBox; } Control Maximizable() { - maximizableCheckBox = new ResettableCheckBox { Text = "Maximizable" }; + maximizableCheckBox = new CheckBox { Text = "Maximizable" }; + maximizableCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); maximizableCheckBox.CheckedBinding.BindDataContext((Window w) => w.Maximizable); return maximizableCheckBox; } Control MovableByWindowBackground() { - movableByWindowBackgroundCheckBox = new ResettableCheckBox { Text = "MovableByWindowBackground" }; + movableByWindowBackgroundCheckBox = new CheckBox { Text = "MovableByWindowBackground" }; + movableByWindowBackgroundCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); movableByWindowBackgroundCheckBox.CheckedBinding.BindDataContext((Window w) => w.MovableByWindowBackground); return movableByWindowBackgroundCheckBox; } Control Minimizable() { - minimizableCheckBox = new ResettableCheckBox { Text = "Minimizable" }; + minimizableCheckBox = new CheckBox { Text = "Minimizable" }; + minimizableCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); minimizableCheckBox.CheckedBinding.BindDataContext((Window w) => w.Minimizable); return minimizableCheckBox; } Control ShowInTaskBar() { - showInTaskBarCheckBox = new ResettableCheckBox { Text = "Show In TaskBar" }; + showInTaskBarCheckBox = new CheckBox { Text = "Show In TaskBar" }; + showInTaskBarCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); showInTaskBarCheckBox.CheckedBinding.BindDataContext((Window w) => w.ShowInTaskbar); return showInTaskBarCheckBox; } Control CreateCanFocus() { - canFocusCheckBox = new ResettableCheckBox { Text = "CanFocus" }; + canFocusCheckBox = new CheckBox { Text = "CanFocus" }; + canFocusCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); canFocusCheckBox.CheckedBinding.BindDataContext((Form w) => w.CanFocus); return canFocusCheckBox; } Control TopMost() { - topMostCheckBox = new ResettableCheckBox { Text = "Top Most" }; + topMostCheckBox = new CheckBox { Text = "Top Most" }; + topMostCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); topMostCheckBox.CheckedBinding.BindDataContext((Window w) => w.Topmost); return topMostCheckBox; } Control VisibleCheckbox() { - visibleCheckBox = new ResettableCheckBox { Text = "Visible" }; + visibleCheckBox = new CheckBox { Text = "Visible" }; + visibleCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow w) => w.ThreeState); visibleCheckBox.CheckedBinding.BindDataContext((Window w) => w.Visible); return visibleCheckBox; } Control CreateShowActivatedCheckbox() { - showActivatedCheckBox = new ResettableCheckBox { Text = "ShowActivated" }; + showActivatedCheckBox = new CheckBox { Text = "ShowActivated" }; + showActivatedCheckBox.BindDataContext(c => c.ThreeState, (SettingsWindow s) => s.ThreeState); showActivatedCheckBox.CheckedBinding.BindDataContext((Form w) => w.ShowActivated); showActivatedCheckBox.Bind(c => c.Enabled, typeRadio, Binding.Property((RadioButtonList t) => t.SelectedKey).ToBool("dialog").Convert(v => !v)); return showActivatedCheckBox; @@ -472,7 +472,8 @@ void CreateChild() child.SizeChanged += child_SizeChanged; child.Title = "Child Window"; - child.WindowStyle = styleCombo.SelectedValue; + if (styleCombo.Enabled) + child.WindowStyle = styleCombo.SelectedValue; child.WindowState = stateCombo.SelectedValue; if (topMostCheckBox.Checked != null) child.Topmost = topMostCheckBox.Checked ?? false; @@ -509,7 +510,7 @@ void CreateChild() void child_Closed(object sender, EventArgs e) { Log.Write(child, "Closed"); - DataContext = null; + DataContext = settings; child.OwnerChanged -= child_OwnerChanged; child.WindowStateChanged -= child_WindowStateChanged; child.Closed -= child_Closed;