2017-02-17 3 views
2

2つのリストボックスがあり、両方が2つの異なるXMLファイルにバインドされています。 目的は、XmlElementsをあるファイルから別のファイル(ListBox)にドラッグすることです。XmlElementを1つのリストボックスから別の空のXMLバインドリストボックスにドラッグ

入力されたListBoxから他の入力されたListBoxにドラッグすると、ターゲットのListBoxのコードはかなり簡単です。 しかし、ターゲットListBoxが空の場合、ListBoxにはアイテムが含まれていないため、XmlElementsを取得することは困難です。

ターゲットはコードがで失敗します移入されませんので:

XmlElement targetXmlElement = (XmlElement)parent.Items.GetItemAt(0);

そこで質問です:私は、リストボックス、ターゲットからにXmlDataProviderまたはXmlDocumentオブジェクトを手に入れるにはどうすればよいListBox parent = (ListBox)sender;

もう1つの問題は、target-listboxに、ドラッグされた要素のターゲットである子ノードのリストが含まれていることです。 親要素へのアクセス方法を教えてください。

ListBox dragSource = null; 
    private void FoodListBox_PreviewMouseLeftButtonDown(object sender, MouseButtonEventArgs e) 
    { 
     ListBox parent = (ListBox)sender; 
     dragSource = parent; 
     object data = GetDataFromListBox(dragSource, e.GetPosition(parent)); 

     if (data != null) 
     { 
      DragDrop.DoDragDrop(parent, data, DragDropEffects.Copy); 
     } 
    } 

    #region GetDataFromListBox(Listbox, Point) 
     private static object GetDataFromListBox(ListBox source, Point point) 
     { 
      UIElement element = source.InputHitTest(point) as UIElement; 
      if(element != null) 
      { 
       object data = DependencyProperty.UnsetValue; 
       while(data == DependencyProperty.UnsetValue) 
       { 
        data = source.ItemContainerGenerator.ItemFromContainer(element); 
        if (data == DependencyProperty.UnsetValue) 
        { 
         element = VisualTreeHelper.GetParent(element) as UIElement; 
        } 
        if (element == source) 
        { 
         return null; 
        } 
       }  
       if(data != DependencyProperty.UnsetValue) 
       { 
        return data; 
       }   
      } 

      return null; 
     } 
    #endregion 


    //This listbox is bound to Dataprovider2, Objects dragged into will access the XML target 
    private void ListBox_Drop(object sender, DragEventArgs e) 
    { 
     ListBox parent = (ListBox)sender; 

     //Get access to the element from the source XML 
     XmlElement sourceXmlElement = (XmlElement)e.Data.GetData(typeof(XmlElement)); 

     //Get the position of the parent to any Element in the the target list (e.g the zero element) 
     XmlElement targetXmlElement = (XmlElement)parent.Items.GetItemAt(0); 

     AppendXmlNode(sourceXmlElement, targetXmlElement); 
    } 
+0

xpathは何も返しません。 –

答えて

1

WPFでは、コレクションに直接バインドするのではなく、そのコレクションのdefault viewにバインドします。

すべてのコレクションにはデフォルトのCollectionViewがあります。 WPFは常にコレクションではなく ビューにバインドします。コレクションに直接バインドする場合、 WPFは実際にそのコレクションの既定のビューにバインドします。この デフォルトビューは、コレクションへのすべてのバインディングによって共有され、 コレクションへのすべての直接バインディングは、ソート、フィルタ、グループ グループ、および1つのデフォルトビューの現在のアイテム特性を共有します。

フィルタリングされたビューをフェッチするのではなく、バインディングソースからXmlDocumentを抽出することができます。

private void targetListBox_Drop(object sender, DragEventArgs e) 
{ 
    ListBox parent = (ListBox)sender; 

    //Get access to the element from the source XML 
    XmlElement sourceXmlElement = (XmlElement)e.Data.GetData(typeof(XmlElement)); 

    //Get access to the document from the target XML 
    BindingExpression bindingExpression = 
     parent.GetBindingExpression(ListBox.ItemsSourceProperty); 
    Binding parentBinding = bindingExpression.ParentBinding; 
    XmlDataProvider source = (XmlDataProvider)parentBinding.Source; 
    XmlDocument targetXmldocument = source.Document; 

    AppendXmlNode(sourceXmlElement, targetXmldocument); 
} 

ドキュメントを入手したら、修正は簡単です。

private static void AppendXmlNode(XmlElement element, XmlDocument doc) 
{ 
    //Get access to the root node to append child 
    XmlNode root = doc.SelectSingleNode("/recipelist/recipe[contains(.,'name')]/foodlist"); 
    //Detach element from source XmlDocument 
    XmlNode clone = doc.ImportNode(element, true); 
    root.AppendChild(clone); 
} 
1

ありがとうございましたbab7lon!

コードスニペットは、しかし、ヌルとしてsourceを返しました:

BindingExpression bindingExpression = parent.GetBindingExpression(ListBox.ItemsSourceProperty); 
Binding parentBinding = bindingExpression.ParentBinding; 
XmlDataProvider source = (XmlDataProvider)parentBinding.Source; 

しかし、私はobject senderが実際のDataContextが含まれていることをしばらく実現しました。次のコードは私の問題を解決し

リストボックス・ターゲットは、XPath = "/ recipelist /レシピ/ foodlist/foodtype [含まれています( '名'。)]" foodlistという意味でろ過され
private void ListBox_Drop(object sender, DragEventArgs e) 
    { 
     ListBox parent = (ListBox)sender; 

     //Get access to the element from the source XML 
     XmlElement sourceXmlElement = (XmlElement)e.Data.GetData(typeof(XmlElement)); 

     XmlDataProvider l_context = (XmlDataProvider)parent.DataContext; 
     XmlDocument l_XmlDoc = l_context.Document; 
     string l_Xpath = l_context.XPath; 
     XmlNode l_node = l_XmlDoc.SelectSingleNode(l_Xpath.Replace("/foodlist/foodtype","")); 
     XmlElement targetXmlElement = (XmlElement)l_node.SelectSingleNode("foodlist"); 

     AppendXmlNode(sourceXmlElement, targetXmlElement); 
    } 

    private void AppendXmlNode(XmlElement source, XmlElement target) 
    { 
     XmlElement l_source = source; 
     XmlElement l_target = target; 

     //Append first the Parent 
     XmlNode l_nodeToCopy = l_target.OwnerDocument.ImportNode(l_source, true); 
     l_target.AppendChild(l_nodeToCopy); 

     XmlDocument l_doc = l_target.OwnerDocument; 
     Save(l_doc); 
    } 
+0

私のスニペットは、リソースとしてXmlDataProviderを使用します(ref [docs](https://msdn.microsoft.com/en-us/library/ms749287(v=vs.110).aspx)) 。それからもう一度、猫の皮膚には複数の方法があります。 – bab7lon

関連する問題