WPF控制DLL问题

时间:2009-08-19 13:41:45

标签: wpf

我已经开始研究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的正确方法是什么?

2 个答案:

答案 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))