我已经开始研究WPF控件dll,它将从winforms应用程序中引用。
我在这个项目中的第一个控件是一个简单的容器控件。它的目的是为Winforms应用程序提供一个模态,透明的对接窗口。
我对这个控件的问题是当我试图拖动它时我无法移动它。如果我不把它放进.dll,我可以移动它。在dll中,Canvas.GetLeft - 返回一个无效的数字,我不知道如何解决这个问题。
以下是此控件的大部分XAML:
<Grid Height="Auto">
<Grid.Resources>
<LinearGradientBrush x:Key="BackBrush" EndPoint="0.5,1" StartPoint="0.5,0">
<GradientStop Color="#C4000000"/>
<GradientStop Offset="1" Color="#66000000"/>
<GradientStop Color="#61000000" Offset="0.50400000810623169"/>
</LinearGradientBrush>
</Grid.Resources>
<Border Height="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Width="Auto" Margin="0,0,0,0" BorderBrush="#FF000000" BorderThickness="2,2,2,2" Background="{StaticResource BackBrush}" Opacity="1" CornerRadius="8,8,8,8">
<StackPanel Background="{x:Null}" Opacity="1" Height="Auto" Width="Auto" HorizontalAlignment="Stretch" VerticalAlignment="Top" x:Name="spWhatAreYouDoing">
<ContentControl></ContentControl>
</StackPanel>
</Border>
<Thumb Background="{x:Null}" Opacity="0" DragDelta="onDragDelta" x:Name="panelthumb"/>
</Grid>
我在后面的代码中钩住了Thumb的onDragDelta事件,并使用它来拖动这个窗口。 当我在同一个.exe中使用它时,这种方法很好。
public void onDragDelta(object sender, System.Windows.Controls.Primitives.DragDeltaEventArgs e)
{
Canvas.SetLeft(this, Canvas.GetLeft(this) + e.HorizontalChange);
Canvas.SetTop(this, Canvas.GetTop(this) + e.VerticalChange);
}
当我从.exe中取出相同的代码并将其放入.dll然后引用.dll并使用我的exe中的控件 - 它将不再拖动。窗口显示但不会移动。
它不会被移动的原因是因为Canvas.GetLeft(this)返回的是无效数字。为什么?虽然此控件的目标是Winforms应用程序的使用,但是当我在没有任何ElementHost干预的情况下从WPF应用程序使用它时,我发现了相同的行为。
编辑 - 当我使用ElementHost直接在Winforms应用程序中托管此控件时,我可以移动窗口。但窗口透明度丢失了。因此,为此表单转移到WPF的完整原因是无效的。
所以我做错了 - 从.dll托管的控件中调用GetLeft的正确方法是什么?
答案 0 :(得分:0)
我建议你先在WinForm中托管WPF控件。禁用WinForm的所有边框属性...因此您的控件看起来就像它本身一样。然后使用此WinForm作为使用您的控件的主要方法。
通过这种方式,您可以访问所有相关功能。
在要点&gt;&gt;&gt; XAML位于独立的Winforms主机中。 &GT;&GT;&GT; Winform将在其他Winforms中用作控件。
答案 1 :(得分:0)
呼。我找到了这个链接,这是我需要的答案才能让它发挥作用。
http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/281a8cdd-69a9-4a4a-9fc3-c039119af8ed
我没有使用Canvas.GetLeft,而是使用获取此控件的绝对位置的代码,然后引发容器可以监视的事件以了解何时移动:
'// Get absolute location on screen of upper left corner of button
Dim locationFromScreen As Point = Me.PointToScreen(New Point(0, 0))
'// Transform screen point to WPF device independent point
Dim source As PresentationSource = PresentationSource.FromVisual(Me)
Dim targetPoints As System.Windows.Point = source.CompositionTarget.TransformFromDevice.Transform(locationFromScreen)
Dim left As Double = targetPoints.X
Dim top As Double = targetPoints.Y
left += e.HorizontalChange
top += e.VerticalChange
Canvas.SetLeft(Me, left)
Canvas.SetTop(Me, top)
'spread the news
PaletteMoved(New DockingPaletteEventArgs(left, top, e.HorizontalChange, e.VerticalChange))