Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

ScrollViewer is not working in WPF WindowsFormHost

enter image description hereI have WindowsFormHost with a RichTextBox in my WPF form, i have given ScrollViewer for that WindowsFormHost but its not working, WindowsFormHost going outside of ScrollViewer...

My XAML is..

<ScrollViewer Background="DarkOrange" VerticalScrollBarVisibility="Auto" Height="80" MaxHeight="85" Margin="11,243,12,218" Width="756">
        <Canvas Height="100" Name="canvas1" Width="auto" >
            <WindowsFormsHost ClipToBounds="True" Height="120" Width="715" Margin="10,5,0,0" Name="winHostTEst" Background="Gray">
                <wf:RichTextBox BackColor="Cornsilk" Text="RichTextBox" x:Name="richTbTest" BorderStyle="None" Enabled="True" ForeColor="Black" Width="550" Multiline="True" ReadOnly="True" />
            </WindowsFormsHost>
        </Canvas>
    </ScrollViewer>

Here are two links with solution of this problem, but i am not able to implement that.. Please have a look to these links also and solve my problem..

links are:

http://blogs.msdn.com/b/ryanvog/archive/2009/01/20/clipping-legacy-content-hosted-inside-a-wpf-scrolling-region.aspx

http://www.mycsharp.de/wbb2/thread.php?threadid=76625

Thanks in advance..

like image 496
Avinash Singh Avatar asked Dec 29 '12 10:12

Avinash Singh


1 Answers

Finally got the solution

Create this Class in your solution for above problem, and take new class control (ScrollViewerWindowsFormsHost) instead of WindowsFormsHost

using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Diagnostics;
using System.Linq;
using System.Text;
using System.Windows.Forms.Integration;
using System.Windows.Media;
using System.Runtime.InteropServices;
using System.Windows;
using System.Windows.Controls;

namespace WPFRichTextBox
{
class ScrollViewerWindowsFormsHost: WindowsFormsHost
{

    protected override void OnWindowPositionChanged(Rect rcBoundingBox)
    {
        base.OnWindowPositionChanged(rcBoundingBox);

        if (ParentScrollViewer == null)
            return;

        GeneralTransform tr = ParentScrollViewer.TransformToAncestor(MainWindow);
        var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight));
        scrollRect = tr.TransformBounds(scrollRect);

        var intersect = Rect.Intersect(scrollRect, rcBoundingBox);
        if (!intersect.IsEmpty)
        {
            tr = MainWindow.TransformToDescendant(this);
            intersect = tr.TransformBounds(intersect);
        }

        SetRegion(intersect);
    }

    protected override void OnVisualParentChanged(DependencyObject oldParent)
    {
        base.OnVisualParentChanged(oldParent);
        ParentScrollViewer = null;

        var p = Parent as FrameworkElement;
        while (p != null)
        {
            if (p is ScrollViewer)
            {
                ParentScrollViewer = (ScrollViewer)p;
                break;
            }

            p = p.Parent as FrameworkElement;
        }
    }

    private void SetRegion(Rect intersect)
    {
        using (var graphics = System.Drawing.Graphics.FromHwnd(Handle))
            SetWindowRgn(Handle, (new System.Drawing.Region(ConvertRect(intersect))).GetHrgn(graphics), true);
    }

    static System.Drawing.RectangleF ConvertRect(Rect r)
    {
        return new System.Drawing.RectangleF((float)r.X, (float)r.Y, (float)r.Width, (float)r.Height);
    }

    private Window _mainWindow;
    Window MainWindow
    {
        get
        {
            if (_mainWindow == null)
                _mainWindow = Window.GetWindow(this);

            return _mainWindow;
        }
    }

    ScrollViewer ParentScrollViewer { get; set; }

    [DllImport("User32.dll", SetLastError = true)]
    public static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw);
}

}

XAML Code:

<Window x:Class="WPFRichTextBox.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
    xmlns:wf="clr-namespace:System.Windows.Forms;assembly=System.Windows.Forms"
    xmlns:swfh="clr-namespace:WPFRichTextBox"
    Title="MainWindow" Height="600" Width="800" Background="LightBlue">
<Grid Loaded="Grid_Loaded">

    <ScrollViewer  Background="DarkOrange" VerticalScrollBarVisibility="Auto" Height="100"  Margin="11,160,12,301" Width="756" Name="scrollViewer1">
        <Canvas Height="200" Name="canvas1" Width="auto" >
      <swfh:ScrollableWindowsFormsHost ClipToBounds="True" Height="194" Width="715" Margin="10,5,0,0" Background="Gray">
                <wf:RichTextBox BackColor="Cornsilk" Text="RichTextBox" x:Name="richTbTest" BorderStyle="None" Enabled="True" ForeColor="Black" Width="550" Multiline="True" ReadOnly="True" />
      </swfh:ScrollableWindowsFormsHost>
        </Canvas>
    </ScrollViewer>
</Grid>

like image 62
Avinash Singh Avatar answered Sep 28 '22 14:09

Avinash Singh