0
votes

I am writing a simple addressbook example application in WPF in which I have a listview that holds the contacts as User objects, but each item is represented with a TextBlock only showing the name.

What I want to achieve is that a user can drag the item onto a "group". Groups are presented on the left hand side of the window. It is a simple grid column with several TextBlock items.

My relevant codebehind:

    /** Display Contact in the contact pane**/
    private void lstItemContact_MouseDown(object sender, MouseButtonEventArgs e)
    {

        ListViewItem item = (ListViewItem)sender;

        User selectedUser = (User) item.Content;

        DragDrop.DoDragDrop(lstContacts, item, DragDropEffects.Move);

        contactPane.Fullname = selectedUser.Name;
        contactPane.Email = selectedUser.Mail;
    }

    private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
    {
        User dropped_user = (User)sender;

        MessageBox.Show(dropped_user.Name);
    }

And the XAML:

<ListView x:Name="lstContacts" Width="250" Grid.Row="1" Grid.Column="1">
        <ListView.View>
            <GridView>
                <GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}" />
            </GridView>
        </ListView.View>

        <ListView.GroupStyle>
            <GroupStyle>
                <GroupStyle.HeaderTemplate>
                    <DataTemplate>
                        <TextBlock x:Name="lstItemContact" FontWeight="Bold" FontSize="14" Text="{Binding Name}" />
                    </DataTemplate>
                </GroupStyle.HeaderTemplate>
            </GroupStyle>
        </ListView.GroupStyle>
        <ListView.ItemContainerStyle>
            <Style TargetType="ListViewItem">
                <EventSetter Event="PreviewMouseLeftButtonDown" Handler="lstItemContact_MouseDown" />
            </Style>                
        </ListView.ItemContainerStyle>
    </ListView>



<TextBlock AllowDrop="True" Drop="tbFavouritesDrop_Drop" Name="tbFavouritesDrop">
                    <Border CornerRadius="3" Background="OrangeRed" Height="7" Width="7" VerticalAlignment="Center" Margin="0 0 2 5"/>
                    <Label FontFamily="Segoe UI Light" FontSize="14" Padding="0">Favourites</Label>
                </TextBlock>

Once I drag the Item onto the "Favourites" Group I get the following error: Additional information: Unable to cast object of type 'System.Windows.Controls.TextBlock' to type 'AddressBook1.User' enter image description here

I am not sure what the exact problem is? Is the problem, that my listview item is a textblock ? The item I am sending is a User Object, and that reaches tbFavouritesDrop_Drop as well.

EDIT 1:

I have changed my Drop event handler to:

private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
        {
            TextBlock item = (TextBlock)sender;

            MessageBox.Show(item.Text);
        }

No exception is thrown, however, the .Text property is empty.

1
My suspicion is that if you set a breakpoint and step through, the exception is actually happening a line above where it appears to be happening. (The stack trace will tell you if you ever made it into the DoDragDrop method)theB

1 Answers

0
votes

Ok, I found a solution after going crazy from another thread: WPF Drag and Drop - Get original source info from DragEventArgs

Which leaves me with:

/** Display Contact in the contact pane**/
    private void lstItemContact_MouseDown(object sender, MouseButtonEventArgs e)
    {

        ListViewItem item = (ListViewItem)sender;

        User selectedUser = (User) item.Content;

        contactPane.Fullname = selectedUser.Name;
        contactPane.Email = selectedUser.Mail;
    }

    private void lstItemContact_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (e.Source != null)
            {
                User selectedItem = (User) lstContacts.SelectedItem;

                DragDrop.DoDragDrop(lstContacts, selectedItem, DragDropEffects.Move);
            }
        }
    }

    private void tbFavouritesDrop_Drop(object sender, DragEventArgs e)
    {
        User selectedUser = e.Data.GetData("AddressBook1.User") as User;
        MessageBox.Show(selectedUser.Name);

    }

I hope that helps someone else. The point here was to use e.Data.GetData("AddressBook1.User") and not work with the sender.