tags:

views:

408

answers:

2

I've started work on a WPF controls dll which will be referenced from winforms applications.

My first control in this project is a simple container control. It's purpose in life is to provide a modaless, transparent docking window to the Winforms app.

My problem with this control is that I can't get it to move when I try to drag it. I can move it if I don't put it into a .dll. Inside the dll, Canvas.GetLeft - returns an invalid number, and I don't know how to fix this.

Here's the bulk of the XAML for this control:

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

I've hooked the Thumb's onDragDelta event in the code behind and use that to drag this window around. This works fine when I use it in the same .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);
 }

When I take this same code out of the .exe and place it into a .dll then reference that .dll and use the control from my exe - it won't drag anymore. The window displays but won't move.

The reason it won't be moved is because Canvas.GetLeft(this) is returning an invalid number. Why? Although the destination for this control is usage by a Winforms app, I find this same behavior when I use it from a WPF app without any ElementHost intervention.

Edit - when I host this control directly within my Winforms app using ElementHost I can move the window. But window transparency is lost. And so the entire reason for moving to WPF for this form is invalid.

So I have done this wrong - what is the right way to call GetLeft from within a control hosted from a .dll?

A: 

I suggest you first host the WPF control inside a WinForm. Disable all the border properties of the WinForm...so your control looks as if it is all by itself. Then use this WinForm as the primary means of using your control.

This way you get access to all the related functionality.

In a gist >>> XAML inside a standalone Winforms host. >>> Winform to be used as control in other Winforms.

Chouette
Thanks I should have said this up top, I'll add the edit. When I host this directly within my Winform app, I lose the window transparency. That's not going to work..........
BPerreault
A: 

Whew. I found this link, and it is the answer I needed to get this to work.

http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/281a8cdd-69a9-4a4a-9fc3-c039119af8ed

Instead of using Canvas.GetLeft, I am now using code which obtains the absolute locatin of this control and then raises an event which containers can monitor to know when to move:

    '// 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))
BPerreault