データグリッド内で WindowsFormsHost を使用しているときに、コントロールがグリッドのスクロール可能な領域をオーバーランします。
ここに記載されているソリューションを使用してみましたが、ScrollViewer は WPF WindowsFormHost で動作しません。
ScrollableWindowsFormsHost クラスを使用して、コントロールをスクロール領域に制限することもできます。ただし、セル内を 2 回クリックしない限り、Winforms コントロール (Winforms コンボ ボックスから派生したコントロール) は表示されません (最初にセルにフォーカスをクリックし、2 回目のクリックでコンボボックスを描画します)。これは、ウィンドウの再描画時に再び消えます。 .
xaml から:
<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
}
}