Frage

Ich versuche, die Silverlight DataStateBehavior zu verwenden, es funktioniert gut in den meisten Fällen, in denen ich auf eine Schaltfläche klicken, die Sätze sagen, ein ‚Ausgewählt‘ Eigentum in der Ansicht Modell entweder falsch oder wahr. Die DataStateBehavior dann erzählt die Visual des betreffenden Staat zu gehen.

Wie folgt aus:

   <Button...>
   <i:Interaction.Behaviors>
             <id:DataStateBehavior Binding="{Binding Selected}" Value="True" TrueState="SelectedVisualState" FalseState="DeselectedVisualState"/>
          </i:Interaction.Behaviors>
   </Button>

Die oben genannten Arbeiten in Ordnung. Was ich versuche, obwohl zu tun ist, um es zu bekommen den richtigen Zustand zu versetzen, wenn die Anwendung geladen wird, wenn ich standardmäßig die ‚Ausgewählt‘ Eigenschaft auf dem View-Modell auf true setzen wäre, würde ich keine Änderungen in der Benutzeroberfläche sehen, bis ich klickte auf den Button, um das Ansichtsmodell Eigenschaft zu ändern.

Ich weiß, es gibt mehrere Klassen mit den DataState Sachen beteiligt, einschließlich:

  • BindingListener.cs
  • ConverterHelper.cs
  • DataStateBehavior.cs
  • DataStateSwitchBehavior.cs
  • DataTrigger.cs

wäre Irgendwelche Hinweise gut, Dank

War es hilfreich?

Lösung

Ich werde tatsächlich eine zweite Antwort hinzuzufügen, die ich gerade versucht, und scheint sauberer zu sein, da sie alle in XAML und ohne individuelle Verhalten getan werden kann. Ich werde die andere Antwort nur als Referenz für eine alternative Lösung, da sie verlassen beide arbeiten.

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <ic:GoToStateAction StateName="SelectedVisualState"/>
    </i:EventTrigger>
</i:Interaction.Triggers>

Sie müssen nur auf einen Verweis auf die Microsoft.Expression.Interactions hinzufügen Baugruppe, die Teil der Mischung SDK ist.

xmlns:ic="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions"

Andere Tipps

Versuchen Sie, diese Erweiterung der DataStateBehavior Klasse. Wenn die Zielelementlasten, wird die DataStateBehavior wie beurteilen, wenn die Eigenschaft aktualisiert wurde.

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Windows;

namespace Gusdor.Wpf
{
    /// <summary>
    /// Fix for data state behavior. Behavior will trigger transitions when target element loads.
    /// </summary>
    class DataStateBehaviorFix: Microsoft.Expression.Interactivity.Core.DataStateBehavior
    {
        public bool UseTransitionsOnLoad { get; set; }

        protected override void OnAttached()
        {
            base.OnAttached();

            AssociatedObject.Loaded += AssociatedObject_Loaded;
        }

        protected override void OnDetaching()
        {
            base.OnDetaching();

            AssociatedObject.Loaded -= AssociatedObject_Loaded;
        }

        void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
        {
            Evaluate();
        }

        void Evaluate()
        {
            if (Value == null)
            {
                GotoState(Binding == null, this.AssociatedObject);
            }
            else GotoState(Value.Equals(Binding), this.AssociatedObject);
        }

        /// <summary>
        /// Attempts to change to the named state. Walks up tree to first match.
        /// </summary>
        /// <param name="flag"></param>
        /// <param name="element"></param>
        void GotoState(bool flag, FrameworkElement element)
        {          
            string stateName = flag ? TrueState : FalseState;

            if (HasState(element, stateName))
            {
                bool ret = System.Windows.VisualStateManager.GoToElementState(element, stateName, UseTransitionsOnLoad);
            }
            else if (element.Parent as FrameworkElement != null)
                GotoState(flag, element.Parent as FrameworkElement);
        }
        /// <summary>
        /// Checks if an element has the state named
        /// </summary>
        /// <param name="element"></param>
        /// <param name="stateName"></param>
        /// <returns></returns>
        bool HasState(FrameworkElement element, string stateName)
        {
            var groups = Microsoft.Expression.Interactivity.VisualStateUtilities.GetVisualStateGroups(element).Cast<VisualStateGroup>();

            return groups.Any(p => p.States.Cast<VisualState>().Any(s => s.Name == stateName));
        }
    }
}

Ein Weg, ich dieses Problem gelöst habe, ist ein Verhalten, dass Sie zu Ihrem Steuerelement hinzufügen können es in einen ersten visuellen Zustand beim Laden zu setzen. Hier ist ein einfaches Beispiel:

public class InitialVisualStateBehavior : Behavior<Control>
{
    public static readonly DependencyProperty InitialStateProperty = DependencyProperty.Register(
        "InitialState",
        typeof(string),
        typeof(InitialVisualStateBehavior),
        null);

    public string InitialState
    {
        get { return (string)GetValue(InitialStateProperty); }
        set { SetValue(InitialStateProperty, value); }
    }

    protected override void OnAttached()
    {
        base.OnAttached();

        if (this.AssociatedObject != null)
        {
            this.AssociatedObject.Loaded += new RoutedEventHandler(AssociatedObject_Loaded);
        }
    }

    protected override void OnDetaching()
    {
        base.OnDetaching();

        if (this.AssociatedObject != null)
        {
            this.AssociatedObject.Loaded -= AssociatedObject_Loaded;
        }
    }

    private void AssociatedObject_Loaded(object sender, RoutedEventArgs e)
    {
        VisualStateManager.GoToState(this.AssociatedObject, this.InitialState, false);
    }
}

Sie würden dann fügen Sie einfach dieses Verhalten auf die Usercontrol-Ebene in XAML:

<i:Interaction.Behaviors>
    <myi:InitialVisualStateBehavior InitialState="SelectedVisualState" />
</i:Interaction.Behaviors>

Sie können auch dies leicht ändern eine durch Kommata getrennte Liste von Anfangszustände zu akzeptieren, die Sie dann durch geteilt und Schleife könnte, wenn man benötigt, um die Kontrolle in einer Reihe von verschiedenen gegenseitig ausschließenden Zuständen nach dem Laden zu setzen.

Dies könnte auch in eine Triggeraction Refactoring, dass Sie nur von dem Loaded-Ereignisse des Steuer auslösen könnten, ich bin nicht sicher, welche Art und Weise sauberer sein würde.

Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top