2009-02-02 5 views
0

J'essaie d'écrire une implémentation ParentAdapter; Je suis intéressé par la prise en charge au moment de la conception de certains contrôles WPF que j'écris et c'est ainsi que vous gérez la logique personnalisée pour la réparation des éléments dans différents contrôles de conteneur. J'ai commencé petit, avec l'idée de créer une classe dérivée StackPanel qui ne permettrait que des éléments Button être parent au moment du design (oui, je suis conscient que le panneau lui-même a besoin de code pour supporter cela aussi.) J'ai commencé avec quoi Je me suis dit serait la plus simple du ParentAdapter pourrait être:À quoi ressemble une implémentation ParentAdapter simple?

using System; 
using System.Windows; 
using System.Windows.Controls; 
using Microsoft.Windows.Design.Interaction; 
using Microsoft.Windows.Design.Model; 

namespace ControlLibrary.Design 
{ 
    internal class SimplePanelParentAdapter : ParentAdapter 
    { 
     public override bool CanParent(ModelItem parent, Type childType) 
     { 
      return (childType == typeof(Button)); 
     } 

     // moves the child item into the target panel; in this case a SimplePanel 
     public override void Parent(ModelItem newParent, ModelItem child) 
     { 
      using (ModelEditingScope undoContext = newParent.BeginEdit()) 
      { 
       // is this correct? 
       //child.Content.SetValue("I'm in a custom panel!"); 
       SimplePanel pnl = newParent.GetCurrentValue() as SimplePanel; 
       pnl.Children.Add(child.GetCurrentValue() as UIElement);     
       undoContext.Complete(); 
      } 

     } 

     public override void RemoveParent(ModelItem currentParent, ModelItem newParent, ModelItem child) 
     { 
      // No special things need to be done, right? 
      child.Content.SetValue("I was in a custom panel."); 
     } 
    } 
} 

Quand je travaille avec ce au moment de la conception, dès que je fais glisser un bouton sur mon panneau personnalisé, un NullReferenceException est jeté du plus profond dans le code VS . Mon code ne lance pas l'exception, parce que je peux avancer tout au long de ma méthode; la pile d'appel indique que le code dans Microsoft.Windows.Design.Developer.dll lève l'exception.

Évidemment, je fais quelque chose de mal, mais la documentation ne fournit aucun exemple et ma recherche-fu semble indiquer que personne n'essaie ceci ou quelqu'un qui l'essaye n'en parle pas. Est-ce que quelqu'un a des suggestions?

Répondre

0

J'ai moi-même trouvé la réponse à ma question. Le problème est dû à l'édition du modèle au lieu de l'encapsuleur ModelItem. Ce que je aurais dû le faire (et fonctionne) est quelque chose comme ceci:

using System; 
using System.Windows.Controls; 
using Microsoft.Windows.Design.Interaction; 
using Microsoft.Windows.Design.Model; 

namespace ControlLibrary.Design 
{ 
    internal class SimplePanelParentAdapter : ParentAdapter 
    { 
     public override bool CanParent(ModelItem parent, Type childType) 
     { 
      return (childType == typeof(Button)); 
     } 

     // moves the child item into the target panel; in this case a SimplePanel 
     public override void Parent(ModelItem newParent, ModelItem child) 
     { 
      using (ModelEditingScope undoContext = newParent.BeginEdit()) 
      { 
       ModelProperty prop = newParent.Properties["Children"]; 
       ModelItemCollection items = (ModelItemCollection)prop.Value; 
       items.Add(child); 

       undoContext.Complete(); 
      } 

     } 

     public override void RemoveParent(ModelItem currentParent, ModelItem newParent, ModelItem child) 
     { 
      using (ModelEditingScope scope = child.BeginEdit()) 
      { 
       ModelProperty prop = currentParent.Properties["Children"]; 
       ((ModelItemCollection)prop.Value).Remove(child); 

       scope.Complete(); 
      } 
     } 
    } 
} 

J'étais confus quand j'ai écrit le premier code et incertain comment je devais appeler Ajouter() sur la propriété des enfants; il ressemble à ModelProperty.Value encapsule des collections avec ModelItemCollection, donc à moins que vous ne fassiez tout votre possible pour que votre classe utilise une interface obtuse cela devrait fonctionner.

Questions connexes