在数据网格中使用 WindowsFormsHost 时,我的控件超出了网格的可滚动区域。
我尝试使用此处提到的解决方案,ScrollViewer 在 WPF WindowsFormHost 中不起作用。
我还可以使用 ScrollableWindowsFormsHost 类将控件限制在滚动区域。然而,除非我在单元格内单击两次(第一次单击单元格上的焦点,第二次单击绘制我的组合框),否则我的 Winforms 控件(这是从 Winforms 组合框派生的控件)不会显示,它在窗口重绘时再次消失.
来自 xml:
<toolkit:DataGridTemplateColumn>
<toolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<controls:HostedWinformsCombobox>
</controls:HostedWinformsCombobox>
</DataTemplate>
</toolkit:DataGridTemplateColumn.CellTemplate>
</toolkit:DataGridTemplateColumn>
来自 ScrollableWindowsFormsHost 的代码。
//--------------------------------------------------------------------------------
/// <summary>Scroll handler manages the clipping of this windows forms host.</summary>
/// <param name="sender">Sender</param>
/// <param name="ea">Event argument</param>
private void ScrollHandler(Object sender, ScrollChangedEventArgs ea)
{
PresentationSource presentationSource = HwndSource.FromVisual(this);
if (presentationSource == null)
{
return;
}
Visual rootVisual = presentationSource.RootVisual;
if (rootVisual == null)
{
return;
}
ScrollViewer scrollViewer = (ScrollViewer)sender;
if (!scrollViewer.IsDescendantOf(rootVisual))
{
return;
}
// calculate the rect of scrollview with 0/0 at upper left corner of root visual
GeneralTransform transform = scrollViewer.TransformToAncestor(rootVisual);
Rect scrollRect = transform.TransformBounds(new Rect(0, 0, scrollViewer.ViewportWidth, scrollViewer.ViewportHeight));
// calculate the rect of the scrollable windows forms host instance with 0/0 at upper left corner of root visual
transform = this.TransformToAncestor(rootVisual);
Rect hostRect = transform.TransformBounds(new Rect(this.Padding.Left, this.Padding.Right,
this.RenderSize.Width, this.RenderSize.Height));
// calculate the intersection of the two rect
Rect intersectRect = Rect.Intersect(scrollRect, hostRect);
Int32 topLeftX = 0;
Int32 topLeftY = 0;
Int32 bottomRightX = 0;
Int32 bottomRightY = 0;
if (intersectRect != Rect.Empty)
{
// calculate the HRGN points with 0/0 at upper left corner of scrollable windows forms host instance
//topLeftX = (Int32)(intersectRect.TopLeft.X - hostRect.TopLeft.X);
//topLeftY = (Int32)(intersectRect.TopLeft.Y - hostRect.TopLeft.Y);
//bottomRightX = (Int32)(intersectRect.BottomRight.X - hostRect.TopLeft.X);
//bottomRightY = (Int32)(intersectRect.BottomRight.Y - hostRect.TopLeft.Y);
//modified from original function - this one draws it correctly without drawing over the title bar etc.
topLeftX = (Int32)(intersectRect.TopLeft.X);
topLeftY = (Int32)(intersectRect.TopLeft.Y);
bottomRightX = (Int32)(intersectRect.BottomRight.X);
bottomRightY = (Int32)(intersectRect.BottomRight.Y);
}
// because the CreateRectRgn / SetWindowRgn api calls are slow we call them only if it has a visual effect
if (_topLeftX != topLeftX || _topLeftY != topLeftY || _bottomRightX != bottomRightX || _bottomRightY != bottomRightY)
{
_topLeftX = topLeftX;
_topLeftY = topLeftY;
_bottomRightX = bottomRightX;
_bottomRightY = bottomRightY;
// create HRGN object and set it to the windows forms host instance
IntPtr hrgn = CreateRectRgn(_topLeftX, _topLeftY, _bottomRightX, _bottomRightY);
SetWindowRgn(this.Handle, hrgn, true);
// I tried the following to fix the issue, but neither ones worked
this.UpdateLayout(); //doesn't work
this.Child.Show(); //doesn't work
}
}