ElementHost.cs source code in C# .NET

Source code for the .NET framework in C#

                        

Code:

/ DotNET / DotNET / 8.0 / untmp / WIN_WINDOWS / lh_tools_devdiv_wpf / Windows / wcp / Integration / System / Windows / Integration / ElementHost.cs / 4 / ElementHost.cs

                            using System.Collections.Generic; 
using System.ComponentModel;
using System.ComponentModel.Design.Serialization;
using System.Diagnostics;
using System.Diagnostics.CodeAnalysis; 
using System.Globalization;
using System.Windows.Documents; 
using System.Windows.Interop; 
using System.Windows.Markup;
using System.Windows.Media; 
using System.Security.Permissions;
using MS.Win32;

using SD = System.Drawing; 
using SWF = System.Windows.Forms;
 
using SW = System.Windows; 
using SWC = System.Windows.Controls;
using SWM = System.Windows.Media; 
using SWMI = System.Windows.Media.Imaging;
using SWI = System.Windows.Input;

 
namespace System.Windows.Forms.Integration
{ 
    ///  
    ///     A Windows Forms control that can be used to host a Windows Presentation
    ///     Foundation element. 
    /// 
    [System.ComponentModel.DesignerCategory("code")]
    [ContentProperty("Child")]
    [DefaultEvent("ChildChanged")] 
    [Designer("WindowsFormsIntegration.Design.ElementHostDesigner, WindowsFormsIntegration.Design, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")]
    [DesignerSerializer("WindowsFormsIntegration.Design.ElementHostCodeDomSerializer, WindowsFormsIntegration.Design, Version=1.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a", 
                    "System.ComponentModel.Design.Serialization.CodeDomSerializer, System.Design, Version=2.0.0.0, Culture=neutral, PublicKeyToken=b03f5f7f11d50a3a")] 
    public class ElementHost : Control
    { 
        internal HwndSource _hwndSource;
        /// 
        /// The decorator is used to provide an Adorner layer which is needed to show UI highlights
        /// for focus etc.  In the pure-Avalon case, this would be handled by Window 
        /// 
        private AdornerDecorator _decorator; 
        private AvalonAdapter _hostContainerInternal; 
        private bool _backColorTransparent;
        private SW.UIElement _child; 

        #region Constructors
        /// 
        ///     Initializes a new instance of the ElementHost class. 
        /// 
        ///  
        ///     Overridden to plug the Avalon control into WinForm's layout engines. 
        /// 
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")] 
        public ElementHost()
            : base()
        {
            this._hostContainerInternal = new AvalonAdapter(this); 
            this._decorator = new AdornerDecorator();
            _decorator.Child = this._hostContainerInternal; 
 
            SetStyle(SWF.ControlStyles.SupportsTransparentBackColor, true);
            SetStyle(SWF.ControlStyles.UserPaint, true); 
            SetStyle(SWF.ControlStyles.AllPaintingInWmPaint, true);

            System.Windows.Input.FocusManager.SetIsFocusScope(this._decorator, true);
            //For keyboarding, this listens for WM_CHAR events not handled, so that mnemonics 
            //that are pressed without the ALT key can be handled.
            SWI.InputManager.Current.PostProcessInput += InputManager_PostProcessInput; 
 
            this.SetAutoSizeMode(AutoSizeMode.GrowAndShrink);
            StartPropertyMapping(); 
            SizeChanged += new EventHandler(CallUpdateBackground);
            LocationChanged += new EventHandler(CallUpdateBackground);
        }
        #endregion 

        #region Layout 
 
        /// 
        ///     Overrides the base class implementation of GetPreferredSize to provide 
        ///     correct layout behavior for the hosted Windows Presentation Foundation elements.
        /// 
        public override SD.Size GetPreferredSize(SD.Size proposedSize)
        { 
            if (Disposing)
            { 
                return base.GetPreferredSize(proposedSize); 
            }
 
            proposedSize = HostUtils.IntersectSizes(HostUtils.ConvertZeroOrOneToUnbounded(proposedSize), HostUtils.ConvertZeroToUnbounded(MaximumSize));
            proposedSize = HostUtils.UnionSizes(proposedSize, MinimumSize);

            // Apply the child's scaling, if any 
            Vector scale = (Child == null ? new Vector(1d, 1d) : HostUtils.GetScale(Child));
 
            Size constraints = Convert.ToSystemWindowsSize(proposedSize, scale); 

            // At this point, an unbounded value is represented by Int32.MaxValue: WPF wants double.PositiveInfinity. 
            if (constraints.Width == Int32.MaxValue) { constraints.Width = Double.PositiveInfinity; }
            if (constraints.Height == Int32.MaxValue) { constraints.Height = Double.PositiveInfinity; }

            // Request that control recompute desired size with new constraints. 
            _decorator.Measure(constraints);
            SD.Size prefSize = Convert.ToSystemDrawingSize(_decorator.DesiredSize, scale); 
 
            // WindowsForms guarantees results will be bounded by control Min/MaxSize
            prefSize = HostUtils.IntersectSizes(prefSize, HostUtils.ConvertZeroToUnbounded(MaximumSize)); 
            prefSize = HostUtils.UnionSizes(prefSize, MinimumSize);

            Debug.WriteLineIf(_traceLayout.TraceInfo, String.Format(CultureInfo.CurrentCulture, "AvalonAdapter({0}): MeasureOverride (constraint={1},result={2})", this.Name, proposedSize, prefSize));
            return prefSize; 
        }
 
        ///  
        ///     Gets the default size of the control.
        ///  
        protected override System.Drawing.Size DefaultSize
        {
            get
            { 
                return new SD.Size(200, 100);
            } 
        } 

        ///  
        ///     Gets or sets a value indicating whether the control is
        ///     automatically resized to display its entire contents.
        /// 
        [Browsable(true), EditorBrowsable(EditorBrowsableState.Always)] 
        public override bool AutoSize
        { 
            get 
            {
                return base.AutoSize; 
            }
            set
            {
                base.AutoSize = value; 
            }
        } 
        #endregion Layout 

        #region Containership 
        /// 
        ///     Gets the parent container of the hosted Windows Presentation Foundation element.
        /// 
        [Browsable(false)] 
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public SWC.Panel HostContainer 
        { 
            get { return HostContainerInternal; }
        } 

        /// 
        /// Indicates that the Child property has been changed.
        ///  
        public event EventHandler ChildChanged;
 
        ///  
        ///     Gets or sets the UIElement hosted by the ElementHost control.
        ///  
        [Browsable(false)]
        [DesignerSerializationVisibility(DesignerSerializationVisibility.Hidden)]
        public SW.UIElement Child
        { 
            get
            { 
                return _child; 
            }
            set 
            {
                UIElement oldValue = Child;
#pragma warning disable 1634, 1691
#pragma warning disable 56526 
                _child = value;
#pragma warning restore 1634, 1691, 56526 
                HostContainerInternal.Children.Clear(); 
                if (_child != null)
                { 
                    HostContainerInternal.Children.Add(_child);
                    _propertyMap.ApplyAll();
                    InitializeChildProperties();
                } 
                OnChildChanged(oldValue);
            } 
        } 

        private void OnChildChanged(UIElement oldChild) 
        {
            if (ChildChanged != null)
            {
                ChildChanged(this, new ChildChangedEventArgs(oldChild)); 
            }
        } 
 
        /// 
        /// Raises the Leave event. 
        /// 
        /// 
        protected override void OnLeave(EventArgs e)
        { 
            System.Windows.Input.FocusManager.SetFocusedElement(_decorator, null);
            base.OnLeave(e); 
        } 

        ///  
        /// Raises the GotFocus event.
        /// 
        /// 
        protected override void OnGotFocus(EventArgs e) 
        {
            base.OnGotFocus(e); 
            _decorator.Focus(); 
        }
 
        private void InitializeChildProperties()
        {
            FrameworkElement childFrameworkElement = Child as FrameworkElement;
            if (childFrameworkElement != null) 
            {
                childFrameworkElement.SizeChanged += new SizeChangedEventHandler(childFrameworkElement_SizeChanged); 
                childFrameworkElement.Height = double.NaN; 
                childFrameworkElement.Width = double.NaN;
                childFrameworkElement.Margin = new Thickness(0d); 
                childFrameworkElement.VerticalAlignment = SW.VerticalAlignment.Stretch;
                childFrameworkElement.HorizontalAlignment = SW.HorizontalAlignment.Stretch;

                DesignerProperties.SetIsInDesignMode(childFrameworkElement, this.DesignMode); 

                Vector scale = HostUtils.GetScale(childFrameworkElement); 
                SD.Size maxElementSize = Convert.ToSystemDrawingSize(new Size(childFrameworkElement.MaxWidth, childFrameworkElement.MaxHeight), scale); 
                SD.Size priorMaxSize = HostUtils.ConvertZeroToUnbounded(MaximumSize);
                int maxWidth = Math.Min(priorMaxSize.Width, maxElementSize.Width); 
                int maxHeight = Math.Min(priorMaxSize.Height, maxElementSize.Height);
                MaximumSize = HostUtils.ConvertUnboundedToZero(new SD.Size(maxWidth, maxHeight));
            }
        } 

        ///  
        /// Raises the VisibleChanged event. 
        /// 
        ///  
        protected override void OnVisibleChanged(EventArgs e)
        {
            base.OnVisibleChanged(e);
            UpdateBackground(); 
        }
 
        void CallUpdateBackground(object sender, EventArgs e) 
        {
            UpdateBackground(); 
        }

        void UpdateBackground()
        { 
            OnPropertyChanged("BackgroundImage", BackgroundImage); //Update the background
        } 
 
        void childFrameworkElement_SizeChanged(object sender, SizeChangedEventArgs e)
        { 
            if (AutoSize)
            {
                PerformLayout();
            } 
        }
 
        internal AvalonAdapter HostContainerInternal 
        {
            get 
            {
                return _hostContainerInternal;
            }
        } 
        #endregion Containership
 
        #region Rendering 

        ///  
        ///     Gets or sets a value indicating whether the hosted element has a transparent background.
        /// 
        [DefaultValue(false)]
        public bool BackColorTransparent 
        {
            get { return _backColorTransparent; } 
            set 
            {
                _backColorTransparent = value; 
                UpdateBackground();
            }
        }
 
        /// 
        ///     Hide GDI painting because the HwndTarget is going to just bitblt the root 
        ///     visual on top of everything. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        protected override void OnPaint(SWF.PaintEventArgs e)
        {
            base.OnPaint(e);
        } 

        ///  
        ///     Paint our parent's background into an offscreen HBITMAP. 
        ///     We then draw this as our background in the hosted Avalon
        ///     control's Render() method to support WinForms->Avalon transparency. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        protected override void OnPaintBackground(SWF.PaintEventArgs pevent)
        { 
            base.OnPaintBackground(pevent);
            _decorator.InvalidateVisual(); 
        } 

        internal void InvokePaintBackgroundAndPaint(SWF.Control control, SWF.PaintEventArgs args) 
        {
            this.InvokePaintBackground(control, args);
            this.InvokePaint(control, args);
        } 

        ///  
        /// Renders the control using the provided Graphics object. 
        /// 
        ///  
        protected override void OnPrint(PaintEventArgs e)
        {
            SWMI.RenderTargetBitmap renderBitmap = HostUtils.GetBitmapForFrameworkElement(_decorator);
            if (renderBitmap != null) 
            {
                using (SD.Bitmap bitmap = HostUtils.GetBitmapFromRenderTargetBitmap(this, renderBitmap, new Point(0, 0))) 
                { 
                    e.Graphics.DrawImage(bitmap, SD.Point.Empty);
                } 
            }
        }

        #endregion rendering 

        #region Keyboarding 
        ///  
        ///     Activates the hosted element.
        ///  
        protected override void Select(bool directed, bool forward)
        {
            if (directed == true)
            { 
                SWI.TraversalRequest request = new SWI.TraversalRequest(forward
                                                        ? SWI.FocusNavigationDirection.First 
                                                        : SWI.FocusNavigationDirection.Last); 

                //Currently ignore TabInto's return value 
                (_hwndSource as IKeyboardInputSink).TabInto(request);
            }
            else
            { 
                if (Child != null)
                { 
                    Child.Focus(); 
                }
            } 

            base.Select(directed, forward);
        }
 
        /// 
        ///     Processes a command key, ensuring that the hosted element has an 
        ///     opportunity to handle the command before normal Windows Forms processing. 
        /// 
        ///  
        ///     This will try see if the pressed key is an Avalon accelerator, if so it returns TRUE,
        ///     which tells WinForms to stop trying to process this key.
        /// 
        [SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)] 
        protected override bool ProcessCmdKey(ref System.Windows.Forms.Message msg, System.Windows.Forms.Keys keyData)
        { 
            MSG msg2 = Convert.ToSystemWindowsInteropMSG(msg); 
            SWI.ModifierKeys modifiers = Convert.ToSystemWindowsInputModifierKeys(keyData);
 
            if ((_hwndSource as IKeyboardInputSink).TranslateAccelerator(ref msg2, modifiers))
            {
                return true;
            } 

            return base.ProcessCmdKey(ref msg, keyData); 
        } 

        ///  
        ///     Processes a mnemonic character, ensuring that the hosted element has an opportunity to handle the mnemonic before
        ///     normal Windows Forms processing.
        /// 
        ///  
        ///     This will try see if the pressed key is an Avalon accelerator, if so it tries
        ///     to process the key, which may move focus to the Avalon control. 
        ///  
        [UIPermission(SecurityAction.LinkDemand, Window = UIPermissionWindow.AllWindows)]
        protected override bool ProcessMnemonic(char charCode) 
        {
            string upperKey = Char.ToUpper(charCode, CultureInfo.CurrentCulture).ToString();
            if (SWI.AccessKeyManager.IsKeyRegistered(_hwndSource, upperKey))
            { 
                // ProcessKey doesn't return enough information for us to handle
                // mnemonic cycling reliably.  I.e. we can't tell the difference 
                // between a key which wasn't processed (returns false) from the 
                // case where there is just one element with this key registered
                // (also returns false). 
                SWI.AccessKeyManager.ProcessKey(_hwndSource, upperKey, false);
                return true;
            }
            else 
            {
                return base.ProcessMnemonic(charCode); 
            } 
        }
 
        /// 
        ///     Ensures that all WM_CHAR key messages are forwarded to the hosted element.
        /// 
        ///  
        ///     Grab all WM_CHAR messages as text input to ensure they're sent to
        ///     Avalon.  If Avalon doesn't handle the message, we will call 
        ///     ProcessDialogChar later on. 
        /// 
        protected override bool IsInputChar(char charCode) 
        {
            return true;
        }
 
        /// 
        ///     Catch WM_CHAR messages which weren't handled by Avalon 
        ///     (including mnemonics which were typed without the "Alt" key) 
        /// 
        private void InputManager_PostProcessInput(object sender, SWI.ProcessInputEventArgs e) 
        {
            IKeyboardInputSink ikis = _hwndSource as IKeyboardInputSink;
            if (ikis == null || !ikis.HasFocusWithin())
            { 
                return;
            } 
            if (!e.StagingItem.Input.Handled && e.StagingItem.Input.RoutedEvent == SWI.TextCompositionManager.TextInputEvent) 
            {
                SWI.TextCompositionEventArgs te = (SWI.TextCompositionEventArgs)e.StagingItem.Input; 
                string text = te.Text;
                if (string.IsNullOrEmpty(text))
                {
                    text = te.SystemText; 
                }
                if (!string.IsNullOrEmpty(text)) 
                { 
                    e.StagingItem.Input.Handled = this.ProcessDialogChar(text[0]);
                } 
            }
        }

        ///  
        ///     Enables a window to receive keyboard messages correctly when it is opened modelessly from Windows Forms.
        ///  
        /// The System.Windows.Window which will be opened modelessly. 
        [PermissionSet(SecurityAction.Demand, Name = "FullTrust")]
        public static void EnableModelessKeyboardInterop(SW.Window window) 
        {
            ApplicationInterop.EnableModelessKeyboardInterop(window);
        }
 
        #endregion Keyboarding
 
        #region Window Handling & Misc 
        /// 
        ///     Raises the HandleCreated event. 
        /// 
        protected override void OnHandleCreated(EventArgs e)
        {
            if (_hwndSource != null) 
            {
                DisposeHWndSource(); 
            } 
            SWF.CreateParams cp = this.CreateParams;
 
            HwndSourceParameters HWSParam = new HwndSourceParameters(this.Text, cp.Width, cp.Height);
            HWSParam.WindowClassStyle = cp.ClassStyle;
            HWSParam.WindowStyle = cp.Style;
            HWSParam.ExtendedWindowStyle = cp.ExStyle; 
            HWSParam.ParentWindow = Handle;
            HWSParam.HwndSourceHook = HwndSourceHook; 
 
            _hwndSource = new HwndSource(HWSParam);
            _hwndSource.RootVisual = _decorator; 
            //For keyboarding: Set the IKeyboardInputSite so that keyboard interop works...
            (_hwndSource as IKeyboardInputSink).KeyboardInputSite = (HostContainerInternal as IKeyboardInputSite);
            base.OnHandleCreated(e);
        } 

        ///  
        ///     Hook for the HwndSource.WndProc. 
        /// 
        private IntPtr HwndSourceHook(IntPtr hwnd, int msg, IntPtr wParam, IntPtr lParam, ref bool handled) 
        {
            if (msg == NativeMethods.WM_SETFOCUS && wParam != Handle)
            {
                // wParam != Handle means focus was lost by a window different from this (EH). 
                // The message was sent directly to the HwndSource (by direct mouse input).
                // We need to notify Winforms so it can set the active control and in turn 
                // notify Control.ActiveXImpl in case we are hosted in an unmanaged app. 
                // EH will set focus back to the WPF control from its OnGotFocus method.
                this.Focus(); 
            }

            return IntPtr.Zero; // This value depends on the message being processed, see MSDN for the particular message.
        } 

 
        private void SetHWndSourceWindowPos() 
        {
            if (_hwndSource != null) 
            {
                SafeNativeMethods.SetWindowPos(_hwndSource.Handle, NativeMethods.HWND_TOP, 0, 0, this.Width, this.Height, 0);
            }
        } 

        ///  
        /// Processes Windows messages. 
        /// 
        ///  
        [SecurityPermission(SecurityAction.InheritanceDemand, Flags = SecurityPermissionFlag.UnmanagedCode),
         SecurityPermission(SecurityAction.LinkDemand, Flags = SecurityPermissionFlag.UnmanagedCode)]
        protected override void WndProc(ref Message m)
        { 
            switch (m.Msg)
            { 
                case NativeMethods.WM_MOVE: 
                case NativeMethods.WM_SIZE:
                case NativeMethods.WM_WINDOWPOSCHANGED: 
                case NativeMethods.WM_WINDOWPOSCHANGING:
                    base.WndProc(ref m);
                    SetHWndSourceWindowPos();
                    break; 
                case NativeMethods.WM_PARENTNOTIFY:
                case NativeMethods.WM_REFLECT + NativeMethods.WM_PARENTNOTIFY: 
                    base.WndProc(ref m); 
                    if (HostUtils.LOWORD(m.WParam) == NativeMethods.WM_CREATE)
                    { 
                        this.BeginInvoke(new MethodInvoker(SetHWndSourceWindowPos));
                    }
                    break;
                case NativeMethods.WM_SETREDRAW: 
                    if (!DesignMode && m.WParam == IntPtr.Zero)
                    { 
                        base.WndProc(ref m); 
                    }
                    break; 
                default:
                    base.WndProc(ref m);
                    break;
            } 
        }
 
        ///  
        ///     Scales the parent container and the Windows Forms control.
        ///  
        /// 
        /// 
        protected override void ScaleCore(float dx, float dy)
        { 
            TransformGroup layoutTransforms = new TransformGroup();
            layoutTransforms.Children.Add(_decorator.LayoutTransform); 
            layoutTransforms.Children.Add(new ScaleTransform(dx, dy)); 
            _decorator.LayoutTransform = layoutTransforms;
            base.ScaleCore(dx, dy); 
        }

        /// 
        protected override void Dispose(bool disposing) 
        {
            if (disposing) 
            { 
                try
                { 
                    if (_hostContainerInternal != null)
                    {
                        _hostContainerInternal.Dispose();
                        _hostContainerInternal = null; 
                    }
                } 
                finally 
                {
                    try 
                    {
                        if (_hwndSource != null)
                        {
                            DisposeHWndSource(); 
                        }
                    } 
                    finally 
                    {
                        SWI.InputManager.Current.PostProcessInput -= InputManager_PostProcessInput; 

                        IDisposable disposableChild = Child as IDisposable;
                        if (disposableChild != null)
                        { 
                            disposableChild.Dispose();
                        } 
                    } 
                }
            } 
            base.Dispose(disposing);
        }

        private void DisposeHWndSource() 
        {
            //For keyboarding: As per comment in the Avalon code, this is set to null before disposal 
            (_hwndSource as IKeyboardInputSink).KeyboardInputSite = null; 

            _hwndSource.Dispose(); 
            _hwndSource = null;
        }
        #endregion Window Handling & Misc
 
        #region Property Mapping
 
        ///  
        ///     This initializes the default property mapping for the element host.
        ///     First: it creates a new PropertyMap to store all the mappings, this 
        ///         is exposed to the user as the PropertyMap property.
        ///     Second: it forwards all property Changed events that we want to listen to
        ///         towards the OnPropertyChanged method.
        ///     Third: it registers several default translators, all of which are handled by 
        ///         the ElementHostPropertyTranslator deligate.
        ///  
        private void StartPropertyMapping() 
        {
            _propertyMap = new ElementHostPropertyMap(this); 

            //This forwards property change notification to OnPropertyChanged, since
            //there is no generic way to handle listening to property value changes.
            this.BackColorChanged += this.OnPropertyChangedBackColor; 
            this.BackgroundImageChanged += this.OnPropertyChangedBackgroundImage;
            this.BackgroundImageLayoutChanged += this.OnPropertyChangedBackgroundImageLayout; 
            this.CursorChanged += this.OnPropertyChangedCursor; 
            this.EnabledChanged += this.OnPropertyChangedEnabled;
            this.FontChanged += this.OnPropertyChangedFont; 
            this.ForeColorChanged += this.OnPropertyChangedForeColor;
            this.RightToLeftChanged += this.OnPropertyChangedRightToLeft;
            this.VisibleChanged += this.OnPropertyChangedVisible;
 
            //We forward these property changes, but don't do anything with them.
            this.AutoSizeChanged += this.OnPropertyChangedAutoSize; 
            this.BindingContextChanged += this.OnPropertyChangedBindingContext; 
            this.CausesValidationChanged += this.OnPropertyChangedCausesValidation;
            this.ContextMenuChanged += this.OnPropertyChangedContextMenu; 
            this.ContextMenuStripChanged += this.OnPropertyChangedContextMenuStrip;
            this.DockChanged += this.OnPropertyChangedDock;
            this.LocationChanged += this.OnPropertyChangedLocation;
            this.MarginChanged += this.OnPropertyChangedMargin; 
            this.PaddingChanged += this.OnPropertyChangedPadding;
            this.ParentChanged += this.OnPropertyChangedParent; 
            this.RegionChanged += this.OnPropertyChangedRegion; 
            this.SizeChanged += this.OnPropertyChangedSize;
            this.TabIndexChanged += this.OnPropertyChangedTabIndex; 
            this.TabStopChanged += this.OnPropertyChangedTabStop;
            this.TextChanged += this.OnPropertyChangedText;
        }
 
        /// 
        ///     These delegates just map property changed events to OnPropertyChanged. These are 
        ///     necessary in the WinForms model since there is no common path for property change 
        ///     notification. (Avalon has an OnPropertyChanged method.)
        ///  
        private void OnPropertyChangedBackColor(object sender, System.EventArgs e)
        {
            OnPropertyChanged("BackColor", this.BackColor);
        } 
        private void OnPropertyChangedBackgroundImage(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("BackgroundImage", this.BackgroundImage); 
        }
        private void OnPropertyChangedBackgroundImageLayout(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("BackgroundImageLayout", this.BackgroundImageLayout);
        }
        private void OnPropertyChangedCursor(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("Cursor", this.Cursor); 
        } 
        private void OnPropertyChangedEnabled(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("Enabled", this.Enabled);
        }
        private void OnPropertyChangedFont(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("Font", this.Font);
        } 
        private void OnPropertyChangedForeColor(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("ForeColor", this.ForeColor); 
        }
        private void OnPropertyChangedRightToLeft(object sender, System.EventArgs e)
        {
            OnPropertyChanged("RightToLeft", this.RightToLeft); 
        }
        private void OnPropertyChangedTabStop(object sender, System.EventArgs e) 
        { 
            OnPropertyChanged("TabStop", this.TabStop);
        } 
        private void OnPropertyChangedVisible(object sender, System.EventArgs e)
        {
            OnPropertyChanged("Visible", this.Visible);
        } 

        // These properties don't have default mappings, but are added in case anyone wants to add them 
 
        private void OnPropertyChangedAutoSize(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("AutoSize", this.AutoSize);
        }
        private void OnPropertyChangedPadding(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("Padding", this.Padding);
        } 
        private void OnPropertyChangedBindingContext(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("BindingContext", this.BindingContext); 
        }
        private void OnPropertyChangedCausesValidation(object sender, System.EventArgs e)
        {
            OnPropertyChanged("CausesValidation", this.CausesValidation); 
        }
        private void OnPropertyChangedContextMenu(object sender, System.EventArgs e) 
        { 
            OnPropertyChanged("ContextMenu", this.ContextMenu);
        } 
        private void OnPropertyChangedContextMenuStrip(object sender, System.EventArgs e)
        {
            OnPropertyChanged("ContextMenuStrip", this.ContextMenuStrip);
        } 
        private void OnPropertyChangedDock(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("Dock", this.Dock); 
        }
        private void OnPropertyChangedLocation(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("Location", this.Location);
        }
        private void OnPropertyChangedMargin(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("Margin", this.Margin); 
        } 
        private void OnPropertyChangedParent(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("Parent", this.Parent);
        }
        private void OnPropertyChangedRegion(object sender, System.EventArgs e)
        { 
            OnPropertyChanged("Region", this.Region);
        } 
        private void OnPropertyChangedSize(object sender, System.EventArgs e) 
        {
            OnPropertyChanged("Size", this.Size); 
        }
        private void OnPropertyChangedTabIndex(object sender, System.EventArgs e)
        {
            OnPropertyChanged("TabIndex", this.TabIndex); 
        }
        private void OnPropertyChangedText(object sender, System.EventArgs e) 
        { 
            OnPropertyChanged("Text", this.Text);
        } 


        /// 
        ///     Notifies the property map that a property has changed. 
        /// 
        /// the name of the property which has changed and requires translation 
        /// the new value of the property 
        /// 
        ///     Putting an InheritanceDemand as a defense-in-depth measure, 
        ///     as this provides a hook to the property system that we don't
        ///     want exposed under PartialTrust.
        /// 
        [UIPermissionAttribute(SecurityAction.InheritanceDemand, Window = UIPermissionWindow.AllWindows)] 
        public virtual void OnPropertyChanged(string propertyName, object value)
        { 
            if (PropertyMap != null) 
            {
                PropertyMap.OnPropertyChanged(this, propertyName, value); 
            }
        }

        ///  
        ///     Gets the property map, which determines how setting properties on the
        ///     ElementHost control affects the hosted Windows Presentation Foundation element. 
        ///  
        [Browsable(false)]
        public PropertyMap PropertyMap 
        {
            get { return _propertyMap; }
        }
        private ElementHostPropertyMap _propertyMap; 

        #endregion Property Mapping 
 
        #region Hidden Events
        ///  
        /// Occurs when the value of the BindingContext property changes.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler BindingContextChanged 
        {
            add { base.BindingContextChanged += value; } 
            remove { base.BindingContextChanged -= value; } 
        }
 
        /// 
        /// Occurs when the control is clicked.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler Click
        { 
            add { base.Click += value; } 
            remove { base.Click -= value; }
        } 

        /// 
        /// Occurs when the value of the ClientSize property changes.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler ClientSizeChanged 
        { 
            add { base.ClientSizeChanged += value; }
            remove { base.ClientSizeChanged -= value; } 
        }

        /// 
        /// Occurs when a new control is added to the Control.ControlCollection. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlAdded 
        {
            add { base.ControlAdded += value; } 
            remove { base.ControlAdded -= value; }
        }

        ///  
        /// Occurs when a control is removed from the Control.ControlCollection.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event ControlEventHandler ControlRemoved
        { 
            add { base.ControlRemoved += value; }
            remove { base.ControlRemoved -= value; }
        }
 
        /// 
        /// Occurs when the value of the Cursor property changes. 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler CursorChanged 
        {
            add { base.CursorChanged += value; }
            remove { base.CursorChanged -= value; }
        } 

        ///  
        /// Occurs when the control is double-clicked. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler DoubleClick
        {
            add { base.DoubleClick += value; }
            remove { base.DoubleClick -= value; } 
        }
 
        ///  
        /// Occurs when a drag-and-drop operation is completed.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event DragEventHandler DragDrop
        {
            add { base.DragDrop += value; } 
            remove { base.DragDrop -= value; }
        } 
 
        /// 
        /// Occurs when an object is dragged into the control's bounds. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event DragEventHandler DragEnter
        { 
            add { base.DragEnter += value; }
            remove { base.DragEnter -= value; } 
        } 

        ///  
        /// Occurs when an object is dragged out of the control's bounds.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler DragLeave 
        {
            add { base.DragLeave += value; } 
            remove { base.DragLeave -= value; } 
        }
 
        /// 
        /// Occurs when an object is dragged over the control's bounds.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event DragEventHandler DragOver
        { 
            add { base.DragOver += value; } 
            remove { base.DragOver -= value; }
        } 

        /// 
        /// Occurs when the control is entered.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Enter 
        { 
            add { base.Enter += value; }
            remove { base.Enter -= value; } 
        }

        /// 
        /// Occurs when the Font property value changes. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler FontChanged 
        {
            add { base.FontChanged += value; } 
            remove { base.FontChanged -= value; }
        }

        ///  
        /// Occurs when the ForeColor property value changes.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler ForeColorChanged
        { 
            add { base.ForeColorChanged += value; }
            remove { base.ForeColorChanged -= value; }
        }
 
        /// 
        /// Occurs during a drag operation. 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event GiveFeedbackEventHandler GiveFeedback 
        {
            add { base.GiveFeedback += value; }
            remove { base.GiveFeedback -= value; }
        } 

        ///  
        /// Occurs when the control receives focus. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler GotFocus
        {
            add { base.GotFocus += value; }
            remove { base.GotFocus -= value; } 
        }
 
        ///  
        /// Occurs when a control's display requires redrawing.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event InvalidateEventHandler Invalidated
        {
            add { base.Invalidated += value; } 
            remove { base.Invalidated -= value; }
        } 
 
        /// 
        /// Occurs when a key is pressed while the control has focus. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event KeyEventHandler KeyDown
        { 
            add { base.KeyDown += value; }
            remove { base.KeyDown -= value; } 
        } 

        ///  
        /// Occurs when a key is pressed while the control has focus.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event KeyPressEventHandler KeyPress 
        {
            add { base.KeyPress += value; } 
            remove { base.KeyPress -= value; } 
        }
 
        /// 
        /// Occurs when a key is released while the control has focus.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event KeyEventHandler KeyUp
        { 
            add { base.KeyUp += value; } 
            remove { base.KeyUp -= value; }
        } 

        /// 
        /// Occurs when a control should reposition its child controls.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event LayoutEventHandler Layout 
        { 
            add { base.Layout += value; }
            remove { base.Layout -= value; } 
        }

        /// 
        /// Occurs when the input focus leaves the control. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler Leave 
        {
            add { base.Leave += value; } 
            remove { base.Leave -= value; }
        }

        ///  
        /// Occurs when the control loses focus.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler LostFocus
        { 
            add { base.LostFocus += value; }
            remove { base.LostFocus -= value; }
        }
 
        /// 
        /// Occurs when the control loses mouse capture. 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler MouseCaptureChanged 
        {
            add { base.MouseCaptureChanged += value; }
            remove { base.MouseCaptureChanged -= value; }
        } 

        ///  
        /// Occurs when the control is clicked by the mouse. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event MouseEventHandler MouseClick
        {
            add { base.MouseClick += value; }
            remove { base.MouseClick -= value; } 
        }
 
        ///  
        /// Occurs when the control is double clicked by the mouse.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDoubleClick
        {
            add { base.MouseDoubleClick += value; } 
            remove { base.MouseDoubleClick -= value; }
        } 
 
        /// 
        /// Occurs when the mouse pointer is over the control and a mouse button is pressed. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseDown
        { 
            add { base.MouseDown += value; }
            remove { base.MouseDown -= value; } 
        } 

        ///  
        /// Occurs when the mouse pointer enters the control.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler MouseEnter 
        {
            add { base.MouseEnter += value; } 
            remove { base.MouseEnter -= value; } 
        }
 
        /// 
        /// Occurs when the mouse pointer rests on the control.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler MouseHover
        { 
            add { base.MouseHover += value; } 
            remove { base.MouseHover -= value; }
        } 

        /// 
        /// Occurs when the mouse pointer leaves the control. (
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler MouseLeave 
        { 
            add { base.MouseLeave += value; }
            remove { base.MouseLeave -= value; } 
        }

        /// 
        /// Occurs when the mouse pointer is moved over the control. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event MouseEventHandler MouseMove 
        {
            add { base.MouseMove += value; } 
            remove { base.MouseMove -= value; }
        }

        ///  
        /// Occurs when the mouse pointer is over the control and a mouse button is released.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event MouseEventHandler MouseUp
        { 
            add { base.MouseUp += value; }
            remove { base.MouseUp -= value; }
        }
 
        /// 
        /// Occurs when the mouse wheel moves while the control has focus. 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event MouseEventHandler MouseWheel 
        {
            add { base.MouseWheel += value; }
            remove { base.MouseWheel -= value; }
        } 

        ///  
        /// Occurs when the control's padding changes. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler PaddingChanged
        {
            add { base.PaddingChanged += value; }
            remove { base.PaddingChanged -= value; } 
        }
 
        ///  
        /// Occurs when the control is redrawn.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event PaintEventHandler Paint
        {
            add { base.Paint += value; } 
            remove { base.Paint -= value; }
        } 
 
        /// 
        /// Occurs before the KeyDown event when a key is pressed while focus is on this control. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event PreviewKeyDownEventHandler PreviewKeyDown
        { 
            add { base.PreviewKeyDown += value; }
            remove { base.PreviewKeyDown -= value; } 
        } 

        ///  
        /// Occurs during a drag-and-drop operation and enables the drag source to determine
        /// whether the drag-and-drop operation should be canceled.
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event QueryContinueDragEventHandler QueryContinueDrag
        { 
            add { base.QueryContinueDrag += value; } 
            remove { base.QueryContinueDrag -= value; }
        } 

        /// 
        /// Occurs when the control is resized.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler Resize 
        { 
            add { base.Resize += value; }
            remove { base.Resize -= value; } 
        }

        /// 
        /// Occurs when the RightToLeft property value changes. 
        /// 
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler RightToLeftChanged 
        {
            add { base.RightToLeftChanged += value; } 
            remove { base.RightToLeftChanged -= value; }
        }

        ///  
        /// Occurs when the Size property value changes.
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)] 
        public new event EventHandler SizeChanged
        { 
            add { base.SizeChanged += value; }
            remove { base.SizeChanged -= value; }
        }
 
        /// 
        /// Occurs when the Text property value changes. 
        ///  
        [Browsable(false), EditorBrowsable(EditorBrowsableState.Never)]
        public new event EventHandler TextChanged 
        {
            add { base.TextChanged += value; }
            remove { base.TextChanged -= value; }
        } 
        #endregion
 
        #region DEBUG 
#if DEBUG
        private static readonly TraceSwitch _traceLayout = new TraceSwitch("ElementHostLayout", "Tracks ElementHost layout information."); 
#else
        private static readonly TraceSwitch _traceLayout = null;
#endif
 
        #endregion DEBUG
    } 
 

    #region AvalonAdapter 
    internal class AvalonAdapter : SWC.DockPanel, IDisposable, IKeyboardInputSite
    {
        private ElementHost _hostControl;
 
        [SuppressMessage("Microsoft.Performance", "CA1810:InitializeReferenceTypeStaticFieldsInline")]
        static AvalonAdapter() 
        { 
            //These properties define how tabbing occurs in the DockPanel. To be most like
            //WinForms these are set to use Continue mode as the default. 
            //
            SWI.KeyboardNavigation.DirectionalNavigationProperty.OverrideMetadata(
                    typeof(AvalonAdapter),
                    new FrameworkPropertyMetadata(SWI.KeyboardNavigationMode.Continue)); 
            SWI.KeyboardNavigation.TabNavigationProperty.OverrideMetadata(
                    typeof(AvalonAdapter), 
                    new FrameworkPropertyMetadata(SWI.KeyboardNavigationMode.Continue)); 
        }
 
        /// 
        ///     Creates the Avalon control we use to host
        ///     other WinForms control in Avalon.
        /// 
        public AvalonAdapter(ElementHost hostControl)
        { 
            _hostControl = hostControl; 
        }
 
        ///
        ///   unsink our events
        ///
        public void Dispose() 
        {
            _hostControl = null; 
        } 

        // used to force invalidation of the avalon control's client area. 
        public static readonly DependencyProperty ForceInvalidateProperty =
                DependencyProperty.Register(
                        "ForceInvalidate",
                        typeof(bool), 
                        typeof(AvalonAdapter),
                        new FrameworkPropertyMetadata( 
                                false, 
                                FrameworkPropertyMetadataOptions.AffectsRender));
 
        private static object OnGetForceInvalidate(DependencyObject d)
        {
            return ((AvalonAdapter)d).ForceInvalidate;
        } 

        ///  
        ///     This property is toggled by ElementHost to force the hosted 
        ///     Avalon control to redraw itself
        ///  
        public bool ForceInvalidate
        {
            get { return (bool)GetValue(ForceInvalidateProperty); }
            set { SetValue(ForceInvalidateProperty, value); } 
        }
 
        ///  
        ///     This is a transparency optimization. It looks up the SWF visual heirarchy to
        ///     find the first opaque control. It then uses this color as the background for 
        ///     OnRender. This doesn't work all the time, but is much faster than the bitmap
        ///     conversion.
        /// 
        /// The current control 
        /// The first opaque color found, or Color.Empty if none is found
        private static SD.Color FindSolidColorParent(Control whichControl) 
        { 
            Control control = whichControl;
            while (control.Parent != null) 
            {
                control = control.Parent;
                if (control.BackColor != SD.Color.Empty && control.BackColor.A == 255)
                { 
                    return control.BackColor;
                } 
            } 
            return SD.Color.Empty;
        } 

        #region IKeyboardInputSite
        public void Unregister()
        { 
        }
 
        public bool OnNoMoreTabStops(SWI.TraversalRequest request) 
        {
            //Tabbing out of hosted elements 

            //Select the next control
            bool forward = true;
            Debug.Assert(request != null, "request was null!"); 
            if (request != null)
            { 
                switch (request.FocusNavigationDirection) 
                {
                    case System.Windows.Input.FocusNavigationDirection.Down: 
                    case System.Windows.Input.FocusNavigationDirection.Right:
                    case System.Windows.Input.FocusNavigationDirection.Next:
                        forward = true;
                        break; 
                    case System.Windows.Input.FocusNavigationDirection.Up:
                    case System.Windows.Input.FocusNavigationDirection.Left: 
                    case System.Windows.Input.FocusNavigationDirection.Previous: 
                        forward = false;
                        break; 
                    case System.Windows.Input.FocusNavigationDirection.First:
                    case System.Windows.Input.FocusNavigationDirection.Last:
                        break;
                    default: 
                        Debug.Assert(false, "Unknown FocusNavigationDirection");
                        break; 
                } 
            }
 
            if (_hostControl != null)
            {
                // Get _hostControl's top-most parent.
                Control topMostParent = _hostControl; 
                while (topMostParent.Parent != null)
                { 
                    topMostParent = topMostParent.Parent; 
                }
                return topMostParent.SelectNextControl(_hostControl, forward, true, true, true); 
            }

            return false;
        } 

        public IKeyboardInputSink Sink 
        { 
            get
            { 
                return (_hostControl._hwndSource as IKeyboardInputSink);
            }
        }
        #endregion IKeyboardInputSite 

        protected override System.Windows.Automation.Peers.AutomationPeer OnCreateAutomationPeer() 
        { 
            return new ElementHostAutomationPeer(this);
        } 
    }
    #endregion AvalonAdapter
}

// File provided for Reference Use Only by Microsoft Corporation (c) 2007.
// Copyright (c) Microsoft Corporation. All rights reserved.


                        

Link Menu

Network programming in C#, Network Programming in VB.NET, Network Programming in .NET
This book is available now!
Buy at Amazon US or
Buy at Amazon UK