Frage

Ich versuche, einen Fortschritt Animation auszulösen, wenn immer die Viewmodel / Presentation Model Besetzt ist. Ich habe ein IsBusy Eigentum und das Viewmodel als Datacontext des Usercontrol eingestellt. Was ist der beste Weg, um einen „progressAnimation“ Storyboard auszulösen, wenn die IsBusy Eigenschaft wahr ist? Nur mischen lassen med Ereignis-Trigger auf einer Usercontrol-Ebene hinzufügen, und ich kann nur schaffen Eigenschaft löst in meinen Datenvorlagen.

Die "progressAnimation" ist als eine Ressource in der Benutzersteuerung definiert.

Ich habe versucht, die DataTriggers als Stil auf dem Usercontrol hinzufügen, aber wenn ich versuche, die Storyboard ich die folgende Fehlermeldung zu starten:

'System.Windows.Style' value cannot be assigned to property 'Style' 
of object'Colorful.Control.SearchPanel'. A Storyboard tree in a Style 
cannot specify a TargetName. Remove TargetName 'progressWheel'.

ProgressWheel ist der Name des Objekts ich zu animieren bin versucht, so Zielnamen Entfernen obvisouly nicht das, was ich will.

unter Verwendung von Datenbindungstechniken, anstelle von mit Ereignissen aufzudecken und starten / stoppen Sie die Animation durch den Code

Ich habe gehofft, dies in XAML zu lösen.

War es hilfreich?

Lösung

Was Sie wollen, ist möglich, indem die Animation auf dem progressWheel erklärt selbst: Die XAML:

<UserControl x:Class="TriggerSpike.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="300" Width="300">
<UserControl.Resources>
    <DoubleAnimation x:Key="SearchAnimation" Storyboard.TargetProperty="Opacity" To="1" Duration="0:0:4"/>
    <DoubleAnimation x:Key="StopSearchAnimation" Storyboard.TargetProperty="Opacity" To="0" Duration="0:0:4"/>
</UserControl.Resources>
<StackPanel>
    <TextBlock Name="progressWheel" TextAlignment="Center" Opacity="0">
        <TextBlock.Style>
            <Style>
                <Style.Triggers>
                    <DataTrigger Binding="{Binding IsBusy}" Value="True">
                        <DataTrigger.EnterActions>
                            <BeginStoryboard>
                                <Storyboard>
                                    <StaticResource ResourceKey="SearchAnimation"/>
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.EnterActions>
                        <DataTrigger.ExitActions>
                            <BeginStoryboard>
                                <Storyboard>
                                   <StaticResource ResourceKey="StopSearchAnimation"/> 
                                </Storyboard>
                            </BeginStoryboard>
                        </DataTrigger.ExitActions>
                    </DataTrigger>
                </Style.Triggers>
            </Style>
        </TextBlock.Style>
        Searching
    </TextBlock>
    <Label Content="Here your search query"/>
    <TextBox Text="{Binding SearchClause}"/>
    <Button Click="Button_Click">Search!</Button>
    <TextBlock Text="{Binding Result}"/>
</StackPanel>

-Code hinter:

    using System.Windows;
using System.Windows.Controls;

namespace TriggerSpike
{
    public partial class UserControl1 : UserControl
    {
        private MyViewModel myModel;

        public UserControl1()
        {
            myModel=new MyViewModel();
            DataContext = myModel;
            InitializeComponent();
        }

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            myModel.Search(myModel.SearchClause);
        }
    }
}

Das Ansichtsmodell:

    using System.ComponentModel;
using System.Threading;
using System.Windows;

namespace TriggerSpike
{
    class MyViewModel:DependencyObject
    {

        public string SearchClause{ get;set;}

        public bool IsBusy
        {
            get { return (bool)GetValue(IsBusyProperty); }
            set { SetValue(IsBusyProperty, value); }
        }

        public static readonly DependencyProperty IsBusyProperty =
            DependencyProperty.Register("IsBusy", typeof(bool), typeof(MyViewModel), new UIPropertyMetadata(false));



        public string Result
        {
            get { return (string)GetValue(ResultProperty); }
            set { SetValue(ResultProperty, value); }
        }

        public static readonly DependencyProperty ResultProperty =
            DependencyProperty.Register("Result", typeof(string), typeof(MyViewModel), new UIPropertyMetadata(string.Empty));

        public void Search(string search_clause)
        {
            Result = string.Empty;
            SearchClause = search_clause;
            var worker = new BackgroundWorker();
            worker.DoWork += worker_DoWork;
            worker.RunWorkerCompleted += worker_RunWorkerCompleted;
            IsBusy = true;
            worker.RunWorkerAsync();
        }

        void worker_RunWorkerCompleted(object sender, RunWorkerCompletedEventArgs e)
        {
            IsBusy=false;
            Result = "Sorry, no results found for: " + SearchClause;
        }

        void worker_DoWork(object sender, DoWorkEventArgs e)
        {
            Thread.Sleep(5000);
        }
    }
}

Hope, das hilft!

Andere Tipps

Auch wenn die Antwort, die die Animation direkt auf das Element schlägt Anbringen animiert wird dieses Problem in einfachen Fällen löst, ist dies nicht wirklich praktikabel, wenn Sie eine komplexen Animationen, die mehrere Elemente zum Ziel benötigt. (Sie können eine Animation zu jedem Element natürlich befestigen, aber es wird ziemlich schrecklich zu verwalten.)

So gibt eine alternative Möglichkeit, dies zu lösen, dass Sie eine Animation ausführen verwenden, um eine DataTrigger kann, die Elemente genannt Zielen.

Es gibt drei Orte, die Sie Trigger in WPF anhängen können: Elemente, Stile und Vorlagen. Allerdings funktionieren hier nicht die ersten beiden Optionen. Die erste ist ausgeschlossen, weil WPF nicht die Verwendung eines DataTrigger direkt auf einem Element unterstützen. (Es gibt keinen besonders guten Grund dafür, soweit ich weiß. Soweit ich mich erinnere, als ich vor Menschen auf dem WPF-Team zu diesem vielen Jahren fragte, sagten sie, sie hätte gern mich unterstützt hat aber nicht Zeit hat, damit es funktioniert.) und -arten ist, weil, wie die Fehlermeldung Sie berichtet haben, sagt, kann man nicht genannte Elemente in einer Animation mit einem Stil zugeordnet Ziel.

Damit lässt Vorlagen. Und Sie können entweder Kontroll- oder Datenvorlagen für diese.

<ContentControl>
    <ContentControl.Template>
        <ControlTemplate TargetType="ContentControl">
            <ControlTemplate.Resources>
                <Storyboard x:Key="myAnimation">

                    <!-- Your animation goes here... -->

                </Storyboard>
            </ControlTemplate.Resources>
            <ControlTemplate.Triggers>
                <DataTrigger
                    Binding="{Binding MyProperty}"
                    Value="DesiredValue">
                    <DataTrigger.EnterActions>
                        <BeginStoryboard
                            x:Name="beginAnimation"
                            Storyboard="{StaticResource myAnimation}" />
                    </DataTrigger.EnterActions>
                    <DataTrigger.ExitActions>
                        <StopStoryboard
                            BeginStoryboardName="beginAnimation" />
                    </DataTrigger.ExitActions>
                </DataTrigger>
            </ControlTemplate.Triggers>

            <!-- Content to be animated goes here -->

        </ControlTemplate>
    </ContentControl.Template>
<ContentControl>

Mit dieser Konstruktion ist WPF glücklich die Animation genannten Elemente in der Vorlage verweisen zu lassen. (Ich habe links sowohl die Animation und die Vorlage Inhalt leer hier -. Sie offensichtlich, dass mit Ihrem eigentlichen Animation nd Inhalt füllen würden)

Der Grund arbeitet in einer Vorlage dies aber kein Stil ist, dass, wenn Sie eine Vorlage anwenden, ist es die genannten Elemente werden immer vorhanden sein definiert, und es ist so sicher für Animationen innerhalb dieser Vorlage Anwendungsbereich definiert auf diese Elemente zu verweisen. Dies ist im Allgemeinen nicht der Fall mit einem Stil, weil Stile auf mehrere verschiedene Elemente angewendet werden kann, von denen jeder kann ganz unterschiedliche visuelle Bäume. (Es ist ein wenig frustrierend, dass es verhindert, dass Sie dies tun, auch in Szenarien, wenn Sie sicher sein können, dass die erforderlichen Elemente da sein, aber vielleicht ist es etwas, das macht es sehr schwierig für die Animation auf die genannten Elemente auf der rechten Seite gebunden zu sein Zeit. ich weiß, es gibt eine ganze Reihe von Optimierungen in WPF-Elemente eines Stil zu ermöglichen, effizient wiederverwendet werden, so vielleicht einer von denen ist, was diese schwierig macht, zu unterstützen.)

Ich würde empfehlen, RoutedEvent zu verwenden, anstatt Ihre IsBusy Eigenschaft. Nur OnBusyStarted und OnBusyStopped Ereignis ausgelöst und verwendet Ereignis-Trigger auf den entsprechenden Elementen.

Sie können auf das Property Ereignis der Dataobject-Klasse zeichnen und ein RoutedEvent Feuer von Usercontrol Ebene machen.

Für RoutedEvent arbeiten wir müssen die Klasse haben von DependancyObject abgeleitet

Sie können Trigger.EnterAction verwenden, um eine Animation zu starten, wenn eine Eigenschaft geändert wird.

<Trigger Property="IsBusy" Value="true">
    <Trigger.EnterActions>
        <BeginStoryboard x:Name="BeginBusy" Storyboard="{StaticResource MyStoryboard}" />
    </Trigger.EnterActions>
    <Trigger.ExitActions>
        <StopStoryboard BeginStoryboardName="BeginBusy" />
    </Trigger.ExitActions>
</Trigger>
Lizenziert unter: CC-BY-SA mit Zuschreibung
Nicht verbunden mit StackOverflow
scroll top