Vra

Ek probeer om 'n vordering animasie aktiveer wanneer ooit die ViewModel / Voorlegging Model is besig. Ek het 'n IsBusy Property, en die ViewModel is ingestel as die DataContext van die UserControl. Wat is die beste manier om 'n "progressAnimation" storie raad aktiveer wanneer die IsBusy eiendom is waar? Meng net laat med Event-Triggers op 'n UserControl vlak voeg, en ek kan net skep eiendom snellers in my data templates.

Die "progressAnimation" word gedefinieer as 'n hulpbron in die gebruiker beheer.

Ek het probeer om die toevoeging van die DataTriggers as 'n styl op die UserControl, maar wanneer ek probeer om die storielyn Ek kry die volgende fout begin:

'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 is die naam van die voorwerp Ek probeer om lewendig te maak, sodat die verwydering teiken naam is obvisouly nie wat ek wil hê.

Ek het gehoop om hierdie op te los in XAML met behulp van data bindend tegnieke, in plaas daarvan om na die gebeure blootstel en begin / stop die animasie deur kode.

Was dit nuttig?

Oplossing

Wat jy wil hê, is moontlik deur te verklaar die animasie op die progressWheel self: 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>

Kode agter:

    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);
        }
    }
}

Die viewmodel:

    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);
        }
    }
}

Hoop dit help!

Ander wenke

Hoewel die antwoord wat direk stel heg die animasie van die element te geanimeerde hierdie probleem in eenvoudige gevalle los, dit is nie regtig werkbare wanneer jy 'n komplekse animasie wat nodig het om verskeie elemente teiken. (Jy kan 'n animasie te heg aan elke element van die kursus, maar dit raak redelik verskriklik om te bestuur.)

Daar is dus 'n alternatiewe manier om dit op te los waarmee jy 'n DataTrigger gebruik om 'n animasie dat teikens vernoem elemente loop.

Daar is drie plekke waar jy kan snellers heg in WPF: elemente, style, en templates. Maar moenie die eerste twee opsies nie hier werk nie. Die eerste is uitgesluit omdat WPF nie die gebruik van 'n DataTrigger direk op 'n element ondersteun. (Daar is geen besonder goeie rede hiervoor, sover ek weet. Sover ek onthou, toe ek mense gevra oor die WPF span oor hierdie baie jare gelede, hulle het gesê hulle wil graag dit te ondersteun, maar het nie het tyd om dit te laat werk.) En style is omdat, as die fout boodskap wat jy het berig sê, jy kan nie die naam van elemente in 'n animasie wat verband hou met 'n styl te rig.

Om te verseker dat templates laat. En jy kan óf beheer of data templates gebruik vir hierdie.

<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>

Met hierdie konstruksie, WPF is gelukkig om jou te laat die animasie verwys na die naam van elemente in die sjabloon. (Ek het beide die animasie en die sjabloon inhoud links hier leë -. Natuurlik jy vul dit met jou werklike animasie de inhoud)

Die rede dit werk in 'n sjabloon, maar nie 'n styl is dat wanneer jy 'n sjabloon van toepassing, die naam van elemente dit definieer sal altyd teenwoordig wees, en dus is dit veilig vir animasies gedefinieer binne bestek se dat template om te verwys na die elemente. Dit is oor die algemeen nie die geval met 'n styl, omdat style aangewend kan word om verskeie verskillende elemente, elk van wat heel anders visuele bome kan hê. (Dit is 'n bietjie frustrerend dat dit verhoed dat jy uit om dit te doen, selfs in scenario's wanneer jy seker is dat die vereiste elemente sal daar kan wees nie, maar miskien is daar iets wat dit baie moeilik maak vir die animasie om gebind te wees om die naam van elemente op die regte tyd. Ek weet daar is nogal 'n baie optimalisaties in WPF om elemente van 'n styl om doeltreffend hergebruik in staat te stel, so miskien een van daardie is wat hierdie moeilike maak om te ondersteun.)

Ek sou aanbeveel om RoutedEvent plaas gebruik van jou IsBusy eiendom. brand net OnBusyStarted en OnBusyStopped gebeurtenis en gebruik Event sneller op die toepaslike elemente.

Jy kan inteken op die PropertyChanged geval van die DataObject klas en maak 'n RoutedEvent vuur uit Usercontrol vlak.

Vir RoutedEvent te werk wat ons nodig het om die klas afgelei van DependancyObject het

Jy kan Trigger.EnterAction gebruik om 'n animasie te begin wanneer 'n eiendom verander.

<Trigger Property="IsBusy" Value="true">
    <Trigger.EnterActions>
        <BeginStoryboard x:Name="BeginBusy" Storyboard="{StaticResource MyStoryboard}" />
    </Trigger.EnterActions>
    <Trigger.ExitActions>
        <StopStoryboard BeginStoryboardName="BeginBusy" />
    </Trigger.ExitActions>
</Trigger>
Gelisensieer onder: CC-BY-SA met toeskrywing
Nie verbonde aan StackOverflow
scroll top