e.data.GetData is always null

2019-07-15 12:38发布

问题:

I am working with Visual Studio 2010, developing an Extension

I need to drag and drop from a WPF TreeView in a Toolwindow onto a DSL Diagram but when I call e.data.GetData I can not get a value and want to know what I am doing wrong

    private void OnDragDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(SqlServerTable)))
        {
            try
            {
                SqlServerTable table = (SqlServerTable)e.Data.GetData(typeof(SqlServerTable));
                MessageBox.Show(table.Name);
            }
            catch (Exception ex)
            {
                MessageBox.Show(ex.Message);
            }
        }
    }

The first if statement resolves as True. This would tell me that it is that sort of Object. This is what is in the WPF Tree view:

        private void DataSourceExplorerTreeView_MouseMove(object sender, MouseEventArgs e)
    {
        if (e.LeftButton == MouseButtonState.Pressed)
        {
            if (DataSourceExplorerTreeView.SelectedValue is TableViewModel)
            {
                Table table = ((TableViewModel)DataSourceExplorerTreeView.SelectedValue).Table;
                DragDrop.DoDragDrop(DataSourceExplorerTreeView, table, DragDropEffects.Copy);
            }
        }
    }

SqlServerTable inherits from Table. If I stick a breakpoint in and call

  e.Data.GetFormats()

I can see my Fully qualified TypeName

回答1:

I have been able to solve this using reflection: MSDN Forum Answer

        private void OnDragDrop(object sender, DragEventArgs e)
    {
        if (e.Data.GetDataPresent(typeof(SqlServerTable)))
        {
          FieldInfo info;

          object obj;

          info = e.Data.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);

          obj = info.GetValue(e.Data);

          info = obj.GetType().GetField("innerData", BindingFlags.NonPublic | BindingFlags.Instance);

         System.Windows.DataObject dataObj = info.GetValue(obj) as System.Windows.DataObject;

         SqlServerTable table = dataObj.GetData("Project.SqlServerTable") as SqlServerTable ;
        }
    }


回答2:

I have not tested your code but I think the problem is in the boxing and unboxing. It seems that you have the wrong type in the MouseMove or DragDrop event. If you want to receive SqlDataTable you should send SqlDataTable not Table, or vice-versa. The GetData() function will return null if it can do the casting.

As a Note: It is not a good practice to use reflection to retrieve private members. If they are private there is a reason for it.