head.WriteLine()

Dienstag, Mai 24, 2011

TT.UIA: Adorner Factory Behaviors

Wie hier und hier bereits beschrieben, haben Expression Blend Behaviors ein paar Limitationen. Hierzu zählt zum Beispiel die Tatsache, dass sie nicht so flexibel wie Adorner sind. So können sie zum Beispiel nur das zugewiesene Element selbst manipulieren und keine zusätzlichen Elemente einfügen. Um diese Limitationen zu umgehen, bietet TT.UIA die Klasse AdornerFactoryBehavior.
Mit ihr kann ein beliebiger Adorner in Form eines Behaviors zugewiesen werden. Beispiel:
<TextBox>
  <i:Interaction.Behaviors>
    <behaviors:AdornerFactoryBehavior
AdornerTypeName="Thinktecture.UIAnnotations.ElementTrackerAdorner" />
  </i:Interaction.Behaviors>
</TextBox>

Dies hat den Vorteil, dass der Adorner sehr einfach mit Expression Blend zugewiesen werden kann.
AdornerFactoryBehaviorInBlend
Darüber hinaus ist es auch möglich, einen Adorner mehrfach dem gleichen Element zuzuweisen, was mit der Attached Property-Syntax nicht möglich ist.
Die meisten Adorner von TT.UIA verfügen jedoch über zusätzliche Eigenschaften, die nicht generisch über AdornerFactoryBehavior zugewiesen werden können. Daher bietet es sich an, eine entsprechende Ableitung zu erstellen. Ein Beispiel hierfür ist die Klasse CueBannerBehavior. Sie kapselt den CueBannerAdorner in dem sie von AdornerFactoryBehavior ableitet und die Eigenschaft CueBannerText bereitstellt.
public class CueBannerAdornerFactoryBehavior
: AdornerFactoryBehavior
{
  protected override Adorner CreateAdorner()
  {
    var adorner = new CueBannerAdorner(this.AssociatedObject);
    adorner.CueBanner = this.CueBannerText;
    return adorner;
  }
  public static readonly DependencyProperty
    CueBannerTextProperty = DependencyProperty.Register(
      "CueBannerText", typeof(string),
      typeof(CueBannerAdornerFactoryBehavior),
      new PropertyMetadata("", 
        OnCueBannerTextPropertyChanged));
  public string CueBannerText
  {
    get { return (string)GetValue(CueBannerTextProperty); }
    set { SetValue(CueBannerTextProperty, value); }
  }
  private static void OnCueBannerTextPropertyChanged(
    DependencyObject sender,
    DependencyPropertyChangedEventArgs e)
  {
    ((CueBannerAdornerFactoryBehavior)sender)
    .OnCueBannerTextChanged(sender, e);
  }
  private void OnCueBannerTextChanged(
    DependencyObject sender,
    DependencyPropertyChangedEventArgs e)
  {
    if (this.Adorner != null && e.NewValue != null)
      ((CueBannerAdorner)this.Adorner)
      .CueBanner = e.NewValue.ToString();
  }
}

Hier wurde zunächst die Methode CreateAdorner() der Basisklasse überschieben und hierin der CueBannerAdorner erstellt. Die Property CueBannerText muss nun lediglich an den Adorner durchgereicht werden.
Im nächsten Post geht es mal nicht um grafische Effekte, sondern den sinnvollen Einsatz von Behaviors in MVVM-Szenarien.

Labels: