2012-12-29 13 views
10

enter image description here में काम नहीं कर रहा मैं अपने WPF रूप में एक RichTextBox साथ WindowsFormHost है, मुझे लगता है कि WindowsFormHost के लिए ScrollViewer दे दिया है, लेकिन इसके काम नहीं कर रहा, WindowsFormHost ScrollViewer के बाहर जा रहा ...ScrollViewer WPF WindowsFormHost

मेरे XAML है। ।

<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> 

यहाँ इस समस्या के समाधान के साथ दो लिंक हैं, लेकिन मुझे लगता है कि लागू करने में सक्षम नहीं कर रहा हूँ .. कृपया इन कड़ियों भी करने के लिए एक नजर है और मेरी समस्या का समाधान ..

लिंक कर रहे हैं:

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

अग्रिम धन्यवाद ..

उत्तर

10

2 के बाद दिन, समाधान

ऊपर समस्या के लिए अपने समाधान में इस कक्षा बनाएँ, और नया वर्ग नियंत्रण (ScrollViewerWindowsFormsHost लेने के लिए) 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); 
} 
,210

}

XAML कोड:

<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> 

+0

मैंने इसे पैरेंट स्क्रॉल व्यूअर के बिना उपयोग किया, लेकिन यह मेरी समस्या है और मेरी समस्या हल हो गई है। मुझे आश्चर्य है कि आपको इसके लिए कोई क्रेडिट कैसे नहीं मिला :) – RoeeK

+0

@RoeeK धन्यवाद :) –

+0

धन्यवाद इससे मुझे बहुत मदद मिली। मुझे पता है कि मुझे देर हो चुकी है लेकिन आप डीपीआई कारक को प्रबंधित करने के लिए एक तरीका जोड़ना चाहते हैं जो गलत आयाम – user1098580

0

क्योंकि ScrollViewer पता नहीं है यह स्क्रॉल करने के लिए है है यही कारण है कि। यदि आपका माउस RichTextBox पर है, तो यह सभी चाबियों को रोक देगा। आप RichTextBox (अर्थात् WndProc) को उपclass कर सकते हैं और mousewheel घटनाओं के लिए सुन सकते हैं और फिर RaiseEvent का उपयोग कर scrollViewer को भेज सकते हैं। यह न भूलें कि WndProc एक अलग धागा WPF से तो आप की तरह कुछ करने की ज़रूरत पर चलता है:

मामले WM_MOUSEWHEEL: Dispatcher.BeginInvoke (नया एक्शन (() => VisualHelper.FindParent (RichTextBox) .RaiseEvent (। सही मापदंडों के साथ .mouse पहिया घटना ..));

7

शायद ज़रुरत पड़े किसी और मेरी बढ़त के मामले में, मैं जहां एक WinForms UserControl एक WPF UserControl, जो अपने आप में एक WinForms अंदर की मेजबानी की है अंदर की मेजबानी की है है फॉर्म (पूछो मत ...) - प्रदान की गई कक्षा अविनाश ने मेरे क्लिपिंग मुद्दों को ठीक नहीं किया।

लेकिन कहीं फोरम थ्रेड पर एक संशोधित संस्करण था, जिसने चाल बनाई - इसलिए मैंने सोचा कि मैं इसे आसानी से यहां पोस्ट करूंगा।

class WindowsFormsHostEx : WindowsFormsHost 
{ 
    private PresentationSource _presentationSource; 

    public WindowsFormsHostEx() 
    { 
     PresentationSource.AddSourceChangedHandler(this, SourceChangedEventHandler); 
    } 

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

     if (ParentScrollViewer == null) 
      return; 

     GeneralTransform tr = RootVisual.TransformToDescendant(ParentScrollViewer); 
     var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight)); 

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

     int x1 = (int)Math.Round(intersect.Left); 
     int y1 = (int)Math.Round(intersect.Top); 
     int x2 = (int)Math.Round(intersect.Right); 
     int y2 = (int)Math.Round(intersect.Bottom); 

     SetRegion(x1, y1, x2, y2); 
    } 

    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 

     if (disposing) 
      PresentationSource.RemoveSourceChangedHandler(this, SourceChangedEventHandler); 
    } 

    private void SourceChangedEventHandler(Object sender, SourceChangedEventArgs e) 
    { 
     ParentScrollViewer = FindParentScrollViewer(); 
    } 

    private ScrollViewer FindParentScrollViewer() 
    { 
     DependencyObject vParent = this; 
     ScrollViewer parentScroll = null; 
     while (vParent != null) 
     { 
      parentScroll = vParent as ScrollViewer; 
      if (parentScroll != null) 
       break; 

      vParent = LogicalTreeHelper.GetParent(vParent); 
     } 
     return parentScroll; 
    } 

    private void SetRegion(int x1, int y1, int x2, int y2) 
    { 
     SetWindowRgn(Handle, CreateRectRgn(x1, y1, x2, y2), true); 
    } 

    private Visual RootVisual 
    { 
     get 
     { 
      if (_presentationSource == null) 
       _presentationSource = PresentationSource.FromVisual(this); 

      return _presentationSource.RootVisual; 
     } 
    } 

    private ScrollViewer ParentScrollViewer { get; set; } 

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

    [DllImport("gdi32.dll")] 
    static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); 
} 
+0

इसमें कोई कमी है - होस्ट किए गए नियंत्रण की स्क्रॉलिंग मानक WindowsFormsHost के साथ उतनी आसान नहीं है। इसके अलावा, यह काम करता है। –

+0

यह मेरे लिए काम करता है जहां स्वीकार किए गए समाधान नहीं थे। विशेष रूप से मैं एक स्क्रॉलग्रेन में एक WPF UserControl में Winforms नियंत्रण होस्ट कर रहा हूँ। – Zachary

1

अवानाश सिंह द्वारा पोस्ट किया गया समाधान मेरे लिए काम नहीं कर रहा है।

मेरा कोड निम्नानुसार है: मैंने ScrollViewerWindowsFormsHost के आसपास कैनवास के साथ और बिना प्रयास किए।

<ext:ScrollViewerWindowsFormsHost x:Name="BrowserHost" ClipToBounds="True" Height="230" Width="Auto" Margin="10,5,0,0" Background="Gray"> 
        <wf:WebBrowser x:Name="VisualEditor" /> 
      </ext:ScrollViewerWindowsFormsHost> 

मेरी कार्यान्वयन में मैं एक खिड़की है कि एक उपकरण पट्टी, एक हैडर अनुभाग (लाल रंग में) के रूप में एक रिबन अभिनय होता है तो एक सीमा के भीतर निहित thats एक विवरण अनुभाग एक ScrollViewer पैनलों (जो usercontrols हैं कि में निहित) आप विस्तार/अनुबंध कर सकते हैं। इनमें से कुछ पैनलों में एक HTML संपादक है जो आपको संकलित दृश्य में या HTML में परिवर्तन करने देता है।

यह वही रूप की तरह इससे पहले कि मैं स्क्रॉल लग रहा है: http://i1377.photobucket.com/albums/ah56/gareth_white1/inside_of_scroll_viewer_zps85098c62.png

यह, जब यह गलत हो जाता है जब मैं ऊपर स्क्रॉल और WebBrowser/ScrollViewerWindowsFormsHost नियंत्रण स्क्रॉल दर्शक के बाहर मेरी हैडर के शीर्ष पर चला जाता है।

अगर मेरी समस्या के प्रकार से कारण है मैं सोच रहा हूँ:

http://i1377.photobucket.com/albums/ah56/gareth_white1/outside_of_scrollviewer_zps35e7fd87.png

क्या मैं ऐसा करना चाहते हैं जब मैं स्क्रॉल नीचे अनुभाग चीजों के पीछे (के सामने नहीं) शीर्षक जाना कि है नियंत्रण मैं होस्ट करने की कोशिश कर रहा हूँ (WebBrowser)।

0

यदि आपके WindowsFormsHost को UserControl के अंदर रखा जाना है, तो answer presented by Avinash काम नहीं कर सकता है। इसलिए मुझे स्क्रॉलव्यूवरविंडोज़फॉर्महोस्ट कक्षा को निम्नानुसार बदलना पड़ा।

public class ScrollViewerWindowsFormsHost : WindowsFormsHost 
    { 
     protected override void OnWindowPositionChanged(Rect rcBoundingBox) 
     { 
      base.OnWindowPositionChanged(rcBoundingBox); 

      if (ParentScrollViewer == null) 
       //return; // Instead, you set the ParentScrollViewr by calling the following method. 
       SetParentScrollViewer(); 

      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); 
     } 

     // This is new a new method. This is called from the above method. 
     private void SetParentScrollViewer() 
     { 
      if (ParentScrollViewer is ScrollViewer) 
       return; // that means its already set; 

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

       p = p.Parent as FrameworkElement; 
      } 
     } 
     // Just comment out this method, you dont need this any more. You set the parent Scroll Viewer by calling SetParentScrollViewer Method. 
     //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); 
    } 

यह है। हर चीज एक ही रहती है।

1

मुझे मार्लन का जवाब सबसे अच्छा लगता है, हालांकि उपयोगकर्ता के पास एक अलग डीपीआई सेटिंग होने पर यह बिल्कुल काम नहीं करता था। यह मार्लन का जवाब है, लेकिन डीपीआई के लिए स्केल करने के लिए हल किया गया। मैंने एक स्थान बदल दिया ईवेंट भी जोड़ा क्योंकि मुझे WindowsFormsHost सामग्री के शीर्ष पर मौजूद पॉपअप को स्क्रॉलव्यूअर में WindowsFormsHost के साथ चलने की आवश्यकता थी।

#region Using Declarations 

using System; 
using System.Runtime.InteropServices; 
using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Forms.Integration; 
using System.Windows.Media; 

#endregion 

public class WindowsFormsHostEx : WindowsFormsHost 
{ 
    #region DllImports 
    [DllImport("User32.dll", SetLastError = true)] 
    static extern int SetWindowRgn(IntPtr hWnd, IntPtr hRgn, bool bRedraw); 

    [DllImport("gdi32.dll")] 
    static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); 

    #endregion 

    #region Events 
    public event EventHandler LocationChanged; 
    #endregion 

    #region Members 
    private PresentationSource _presentationSource; 
    #endregion 

    #region Properties 
    private ScrollViewer ParentScrollViewer { get; set; } 
    private bool Scrolling { get; set; } 
    public bool Resizing { get; set; } 
    private Visual RootVisual 
    { 
     get 
     { 
      _presentationSource = PresentationSource.FromVisual(this); 
      return _presentationSource.RootVisual; 
     } 
    } 
    #endregion 

    #region Constructors 
    public WindowsFormsHostEx() 
    { 
     PresentationSource.AddSourceChangedHandler(this, SourceChangedEventHandler); 
    } 
    #endregion 

    #region Methods 

    protected override void OnWindowPositionChanged(Rect rcBoundingBox) 
    { 
     DpiScale dpiScale = VisualTreeHelper.GetDpi(this); 

     base.OnWindowPositionChanged(rcBoundingBox); 

     Rect newRect = ScaleRectDownFromDPI(rcBoundingBox, dpiScale); 
     Rect finalRect; 
     if (ParentScrollViewer != null) 
     { 
      ParentScrollViewer.ScrollChanged += ParentScrollViewer_ScrollChanged; 
      ParentScrollViewer.SizeChanged += ParentScrollViewer_SizeChanged; 
      ParentScrollViewer.Loaded += ParentScrollViewer_Loaded; 
     } 

     if (Scrolling || Resizing) 
     { 
      if (ParentScrollViewer == null) 
       return; 
      MatrixTransform tr = RootVisual.TransformToDescendant(ParentScrollViewer) as MatrixTransform; 

      var scrollRect = new Rect(new Size(ParentScrollViewer.ViewportWidth, ParentScrollViewer.ViewportHeight)); 
      var c = tr.TransformBounds(newRect); 

      var intersect = Rect.Intersect(scrollRect, c); 
      if (!intersect.IsEmpty) 
      { 
       tr = ParentScrollViewer.TransformToDescendant(this) as MatrixTransform; 
       intersect = tr.TransformBounds(intersect); 
       finalRect = ScaleRectUpToDPI(intersect, dpiScale); 
      } 
      else 
       finalRect = intersect = new Rect(); 

      int x1 = (int)Math.Round(finalRect.X); 
      int y1 = (int)Math.Round(finalRect.Y); 
      int x2 = (int)Math.Round(finalRect.Right); 
      int y2 = (int)Math.Round(finalRect.Bottom); 

      SetRegion(x1, y1, x2, y2); 
      this.Scrolling = false; 
      this.Resizing = false; 

     } 
     LocationChanged?.Invoke(this, new EventArgs()); 
    } 

    private void ParentScrollViewer_Loaded(object sender, RoutedEventArgs e) 
    { 
     this.Resizing = true; 
    } 

    private void ParentScrollViewer_SizeChanged(object sender, SizeChangedEventArgs e) 
    { 
     this.Resizing = true; 
    } 

    private void ParentScrollViewer_ScrollChanged(object sender, ScrollChangedEventArgs e) 
    { 
     if (e.VerticalChange != 0 || e.HorizontalChange != 0 || e.ExtentHeightChange != 0 || e.ExtentWidthChange != 0) 
      Scrolling = true; 
    } 

    protected override void Dispose(bool disposing) 
    { 
     base.Dispose(disposing); 

     if (disposing) 
     { 
      PresentationSource.RemoveSourceChangedHandler(this, SourceChangedEventHandler); 
      _presentationSource = null; 
     } 
    } 

    private void SourceChangedEventHandler(Object sender, SourceChangedEventArgs e) 
    { 
     if (ParentScrollViewer != null) 
     { 
      ParentScrollViewer.ScrollChanged -= ParentScrollViewer_ScrollChanged; 
      ParentScrollViewer.SizeChanged -= ParentScrollViewer_SizeChanged; 
      ParentScrollViewer.Loaded -= ParentScrollViewer_Loaded; 
     } 
     ParentScrollViewer = FindParentScrollViewer(); 
    } 

    private ScrollViewer FindParentScrollViewer() 
    { 
     DependencyObject vParent = this; 
     ScrollViewer parentScroll = null; 
     while (vParent != null) 
     { 
      parentScroll = vParent as ScrollViewer; 
      if (parentScroll != null) 
       break; 

      vParent = LogicalTreeHelper.GetParent(vParent); 
     } 
     return parentScroll; 
    } 

    private void SetRegion(int x1, int y1, int x2, int y2) 
    { 
     SetWindowRgn(Handle, CreateRectRgn(x1, y1, x2, y2), true); 
    } 

    public static Rect ScaleRectDownFromDPI(Rect _sourceRect, DpiScale dpiScale) 
    { 
     double dpiX = dpiScale.DpiScaleX; 
     double dpiY = dpiScale.DpiScaleY; 
     return new Rect(new Point(_sourceRect.X/dpiX, _sourceRect.Y/dpiY), new System.Windows.Size(_sourceRect.Width/dpiX, _sourceRect.Height/dpiY)); 
    } 

    public static Rect ScaleRectUpToDPI(Rect _toScaleUp, DpiScale dpiScale) 
    { 
     double dpiX = dpiScale.DpiScaleX; 
     double dpiY = dpiScale.DpiScaleY; 
     return new Rect(new Point(_toScaleUp.X * dpiX, _toScaleUp.Y * dpiY), new System.Windows.Size(_toScaleUp.Width * dpiX, _toScaleUp.Height * dpiY)); 
    } 
    #endregion 
} 
0

हम कई ScrollViewers उपयोग कर रहे हैं और यह भी एक ViewBox तो उल्लेख किया समाधान में से कोई भी हमारे लिए काम किया। तो यहां हमारे soloution

using System.Windows; 
using System.Windows.Controls; 
using System.Windows.Forms.Integration; 
using System.Windows.Media; 

namespace Something 
{ 
    /// <summary> 
    /// </summary> 
    public class ClippingWindowsFormsHost : WindowsFormsHost 
    { 
     private Rect _previousBounds; 
     private List<ScrollViewer> _scrollViewers; 
     private PresentationSource _source; 

     public ClippingWindowsFormsHost() 
     { 
      PresentationSource.AddSourceChangedHandler(this, _sourceChangedEventHandler); 
     } 

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

     [DllImport("gdi32.dll")] 
     private static extern IntPtr CreateRectRgn(int nLeftRect, int nTopRect, int nRightRect, int nBottomRect); 

     protected override void OnWindowPositionChanged(Rect rcBoundingBox) 
     { 
      if (_previousBounds == rcBoundingBox) 
      { 
       base.OnWindowPositionChanged(rcBoundingBox); 
       return; // optimization 
      } 
      _previousBounds = rcBoundingBox; 

      if (_scrollViewers != null && _scrollViewers.Count != 0) 
      { 
       Rect scrollRect = Rect.Empty; 

       double offsetX = 0d; 
       double offsetY = 0d; 
       // List is in order outer to inner 
       for (int index = 0; index < _scrollViewers.Count; index++) 
       { 
        ScrollViewer scrollViewer = _scrollViewers[index]; 

        MatrixTransform transform = (MatrixTransform) scrollViewer.TransformToAncestor(_source.RootVisual); 

        Rect viewPort = new Rect(0, 0, scrollViewer.ViewportWidth, scrollViewer.ViewportHeight); 
        viewPort = transform.TransformBounds(viewPort); 

        // The ScrollOffset of the innermost Scrollviewer is the one we are interested in, because this is the one that scrolls our content 
        // all others only scroll our position on the screen 
        if (index == _scrollViewers.Count - 1) 
        { 
         Rect scaledScrollOffset = transform.TransformBounds(new Rect(0, 0, scrollViewer.HorizontalOffset, scrollViewer.VerticalOffset)); 

         // We substract our position from the offsets because Clipping works with Controlcoordinates, not Screencoordinates. 
         offsetX = scaledScrollOffset.Width - viewPort.TopLeft.X; 
         offsetY = scaledScrollOffset.Height - viewPort.TopLeft.Y; 
        } 


        scrollRect = scrollRect == Rect.Empty ? viewPort : Rect.Intersect(scrollRect, viewPort); 
       } 

       scrollRect.Offset(offsetX, offsetY); 

       // This transformation is needed to account for any scaling that comes by a sorrounding ViewBox. 
       MatrixTransform mytransform = (MatrixTransform) TransformToAncestor(_source.RootVisual); 
       rcBoundingBox = mytransform.TransformBounds(rcBoundingBox); 


       Rect intersect = Rect.Intersect(new Rect(rcBoundingBox.Size), scrollRect); 

       int x1 = (int) Math.Floor(intersect.X); 
       int y1 = (int) Math.Floor(intersect.Y); 
       int x2 = (int) Math.Floor(intersect.Right); 
       int y2 = (int) Math.Floor(intersect.Bottom); 

       SetWindowRgn(Handle, CreateRectRgn(x1, y1, x2, y2), true); 
      } 

      base.OnWindowPositionChanged(rcBoundingBox); 
     } 

     protected override void Dispose(bool disposing) 
     { 
      base.Dispose(disposing); 

      if (disposing) 
      { 
       PresentationSource.RemoveSourceChangedHandler(this, _sourceChangedEventHandler); 
      } 
     } 

     private void _sourceChangedEventHandler(object sender, SourceChangedEventArgs e) 
     { 
      _scrollViewers = new List<ScrollViewer>(); 
      _source = e.NewSource; 
      DependencyObject parent = this; 
      while ((parent = VisualTreeHelper.GetParent(parent)) != null) 
      { 
       ScrollViewer viewer = parent as ScrollViewer; 
       if (viewer != null) 
        _scrollViewers.Insert(0, viewer); 
      } 
     } 
    } 
} 
संबंधित मुद्दे