2012-04-14 5 views
4

Ich habe ein Verhalten entwickelt, das die Clip-Eigenschaft von AssociatedObject ändert. Wenn ich die Anwendung starte, ist alles in Ordnung. Aber wenn ich die Seite in Blend anschaue, sieht es so aus, als ob das Verhalten das zugehörige Objekt nicht beeinflusst.Silverlight Blend Verhaltensweisen werden zur Entwurfszeit nicht angefügt

Ich habe versucht, "Blend" zu debuggen, indem ich Visual Studio 2010-Debugger an seinen Prozess anfüge und einen Unterbrechungspunkt für die OnAttached-Methode des Verhaltens festlege, aber der Haltepunkt wird nie erreicht. Als ob Blend verhindert, dass dieses Verhalten zur Entwurfszeit angehängt wird.

Gibt es einen Weg um es herum?

Cheers,

+0

Soweit ich weiß, ist dieses Problem auch in WPF mit Visual Studio 2013 (die Blend in seinem Designer integriert hat). Ich komme zu Ihrem Problem, da ich in dieser Umgebung eine ähnliche Situation habe. – FrankyB

Antwort

2

Endlich habe ich einen brauchbaren Weg gefunden, aber es gibt einen großen Vorbehalt, den ich am Ende dieser Antwort stelle. Hier ist mein CustomAttachManager:

public class CustomAttachManager : DependencyObject 
{ 
    #region Object CustomAttachManager.Attached = null 

    public static IAttachedObject GetAttached(DependencyObject obj) { return (IAttachedObject)obj.GetValue(AttachedProperty); } 
    public static void SetAttached(DependencyObject obj, IAttachedObject value) { obj.SetValue(AttachedProperty, value); } 

    public static readonly DependencyProperty AttachedProperty = 
     DependencyProperty.RegisterAttached("Attached", typeof(IAttachedObject), typeof(CustomAttachManager), new PropertyMetadata(null, StaticHandleAttachedChanged)); 

    static void StaticHandleAttachedChanged(DependencyObject self, DependencyPropertyChangedEventArgs args) 
    { 
     var ov = (IAttachedObject)args.OldValue; 
     var nv = (IAttachedObject)args.NewValue; 

     if (ov != null) ov.Detach(); 
     if (nv != null) nv.Attach(self); 
    } 
    #endregion 
} 

Sie können es dann verwenden, um Verhaltensweisen wie diese anhängen:

<my:CustomAttachManager.Attached> 
    <my:RedBackgroundBehavior></my:RedBackgroundBehavior> 
</my:CustomAttachManager.Attached> 

Mein Beispiel Verhalten ändert den Hintergrund eines Panels zu rot, die im Designer sichtbar ist.

Das verbleibende Problem ist der Fall von mehreren Verhaltensweisen. Die beste Lösung, die ich kommen könnte bis ein Proxy:

[ContentProperty("Children")] 
public class MultipleBehavior : Behavior<DependencyObject> 
{ 
    DependencyObjectCollection<IAttachedObject> children = new DependencyObjectCollection<IAttachedObject>(); 
    public DependencyObjectCollection<IAttachedObject> Children { get { return children; } } 

    protected override void OnAttached() 
    { 
     foreach (var child in Children) child.Attach(AssociatedObject); 
    } 

    protected override void OnDetaching() 
    { 
     foreach (var child in Children) child.Detach(); 
    } 
} 

, die auf diese Weise verwendet werden können:

<my:CustomAttachManager.Attached> 
     <my:MultipleBehavior> 
      <my:RedBackgroundBehavior /> 
      <my:SupriseBehavior /> 
     </my:MultipleBehavior> 
    </my:CustomAttachManager.Attached> 

Der Proxy in einen Defekt hat, dass es nicht richtig Verhaltensweisen hinzugefügt, nachdem etwas behandelt bereits angeschlossen, aber das wird im klassischen Anwendungsfall nicht passieren.

Der Vorbehalt ist, dass ich keine Möglichkeit kenne, Blend die Verhaltensweisen im Objektbaum anzuzeigen.Die "AlternateContentProperty" kann nicht verwendet werden, da sie nicht für angefügte Eigenschaften funktioniert. Dies wird von CustomAttachManager verwendet.

Ich werde diese Antwort aktualisieren, wenn ich eine Antwort auf dieses Problem finde.

+0

Thnx, John, das ist eigentlich eine sehr gute Lösung. Ich habe auch meine eigene Verhaltenssammlung für Win8-Shop-Anwendungen implementiert (wo keine Unterstützung für native Verhaltensweisen vorhanden ist) und tatsächlich geschafft, dass sie in der Entwurfszeit arbeiten, obwohl bei mehreren Verhaltensweisen das Problem der Weitergabe des Datenkontexts besteht, wie Sie bemerkt haben in deiner Lösung. –

+0

@KobiHari Wenn Sie etwas Linkbares für das haben, was Sie mit Win8 Store Xaml getan haben, wäre es cool, wenn Sie einen solchen Link hier posten. Ich habe damit noch gar nicht experimentiert und wie es mit Silverlight vergleichbar ist; und vielleicht irgendwann in der Zukunft werde ich müssen. – John

0

Ich bin nicht sicher, aber ich denke, das zugehörige Objekt nur dann beeinträchtigt werden, wenn das Verhalten „angehängt“ wird. Dies wird während des "OnAttached" -Ereignisses aufgerufen und ich glaube nicht, dass dieses Ereignis während der Entwurfszeit aufgerufen wird. Soweit ich weiß, ändert sich die Entwurfszeit während der Initialisierung/Erstellungsphase. OnAttached passiert, nachdem alle diese auftreten (daher der Grund, dass das AssociatedObject für die Manipulation verfügbar ist) und als ein Ergebnis es daher erschwert, dass ein Verhalten ein Steuerelement zur Entwurfszeit ändert. Ich sage nicht, dass es unmöglich ist, aber aus dem scheinbaren Design der Lebensdauer einer Kontrolle sowie einem Verhalten erscheint dieser Ansatz schwierig. Lösungen:

  • Nehmen Sie den Ansatz der Template-Manipulation. Fügen Sie einen benutzerdefinierten Stil oder Ressourcenwörterbuchschlüssel hinzu, den Sie so gestalten, dass die gesuchte Impression erstellt wird.
  • Erstellen Sie ein benutzerdefiniertes Steuerelement in Visual Studio, das eine Eigenschaft verfügbar macht, an die Sie ein anderes Steuerelement binden können. Lassen Sie dieses benutzerdefinierte Steuerelement diese "Eigenschaft" ändern, d. H. Ihr Steuerelement mit der Clip-Eigenschaft während einer der Initialisierungsmethoden. Überprüfen Sie beispielsweise während der InitializeComponent, ob der Inhalt geladen ist, und rufen Sie dann eine Methode zum Anpassen der Eigenschaft "Clip" auf, wenn Sie dies wünschen. Informieren Sie sich über den Lebenszyklus einer Silverlight-Steuerung und dies können Ihnen helfen - http://stuff.seans.com/2009/03/23/hello-silverlight-world-part-3-the-lifecycle-of-a-silverlight-control/

Wie ich schon sagte, ich bin nicht sicher, ob die Antworten hier, aber ich werde sagen, dass dies viel - wenn die Lösung zu kompliziert scheint, es gibt wahrscheinlich einen saubereren Ansatz;)

+0

Neel, wie ich schrieb, ich weiß, dass das Verhalten OnAttached nicht aufgerufen wird, ist die Frage, warum. Es gibt viele verschiedene Ansätze, die ich auswählen kann (z. B. eine angefügte Eigenschaft, die ich ausprobiert habe und die sowohl für die Entwurfszeit als auch für die Laufzeit funktioniert). Da angehängte Verhaltensweisen auf angefügten Eigenschaften basieren, erscheint es ein wenig seltsam, dass sie sich in der Entwurfszeit anders verhalten. Ich frage mich, ob jemand weiß, warum die OnAttached-Methode nicht zur Entwurfszeit aufgerufen wird und ob es etwas gibt, das ich anders machen kann, um es aufzurufen. –

+0

Ahh. Ich glaube, es ist nur ein Teil des Entwicklungszeit-Lebenszyklus. Ich erinnere mich an eine ähnliche Situation, als ich an einem ASP.NET-Projekt arbeitete. Ich machte eine benutzerdefinierte Combo-Box, die ich zur Entwurfszeit etwas vorbelastet sein wollte, und dann wurde mir klar, dass einige Methoden erst zur Laufzeit aufgerufen werden. Ich konnte keine Dokumentation finden, um zu sagen, welche Methoden zur Entwurfszeit aufgerufen werden und welche zur Laufzeit aufgerufen werden. –

+0

Meine letzte Wette besteht darin, sicherzustellen, dass Sie DependencyProperties und keine normalen Eigenschaften verwenden. Oder macht es dasselbe in VS 2010? @KobiHari –

Verwandte Themen