e.data.GetData è sempre null
-
07-07-2019 - |
Domanda
Sto lavorando con Visual Studio 2010, sviluppando un'estensione
Devo trascinare e rilasciare da un TreeView WPF in una finestra degli strumenti in un diagramma DSL ma quando chiamo e.data.GetData non riesco a ottenere un valore e voglio sapere cosa sto facendo di sbagliato
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 prima istruzione if si risolve come True. Questo mi direbbe che è quel tipo di Oggetto. Questo è ciò che è nella vista ad albero 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 eredita dalla tabella. Se inserisco un punto di interruzione e chiamo
e.Data.GetFormats()
Riesco a vedere il mio TypeName completo
Soluzione
Sono stato in grado di risolvere questo problema usando reflection: Risposta 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 ;
}
}
Altri suggerimenti
Non ho testato il tuo codice ma penso che il problema sia nel boxing e nel unboxing. Sembra che tu abbia il tipo sbagliato nell'evento MouseMove o DragDrop. Se desideri ricevere SqlDataTable devi inviare SqlDataTable non Table o viceversa. La funzione GetData () restituirà null se può eseguire il casting.
Nota: non è una buona pratica utilizzare la riflessione per recuperare membri privati. Se sono privati, c'è una ragione per questo.