e.data.GetData est toujours null
-
07-07-2019 - |
Question
Je travaille avec Visual Studio 2010 pour développer une extension
Je dois glisser-déposer d'un arbre WPF dans une fenêtre d'outils sur un diagramme DSL, mais lorsque j'appelle e.data.GetData, je ne peux pas obtenir de valeur et je veux savoir ce que je fais de mal
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);
}
}
}
La première instruction if est résolue en tant que True. Cela me dirait que c'est ce genre d'objet. C’est ce qui se trouve dans l’arborescence WPF:
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 hérite de Table. Si je colle un point d'arrêt et appelle
e.Data.GetFormats()
Je peux voir mon nom de type qualifié complet
La solution
J'ai pu résoudre ce problème à l'aide d'une réflexion: Réponse de forum MSDN
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 ;
}
}
Autres conseils
Je n’ai pas testé votre code mais je pense que le problème réside dans la boxe et le déballage. Il semble que vous ayez un type incorrect dans l'événement MouseMove ou DragDrop. Si vous souhaitez recevoir SqlDataTable, vous devez envoyer SqlDataTable not Table, ou inversement. La fonction GetData () retournera null si elle peut effectuer le casting.
Comme remarque: il n’est pas recommandé d’utiliser la réflexion pour extraire des membres privés. Si elles sont privées, il y a une raison à cela.