2011-06-28 11 views
7

Próbuję przekonwertować niektóre z moich umiejętności WPF na Silverlight i mam do czynienia z nieco dziwnym problemem w testowej mini-aplikacji, nad którą pracowałem. W WPF przyzwyczaiłem się do używania DataTriggerów w stylu do ustawiania właściwości kontrolnych na podstawie właściwości powiązanych danych. Odkryłem, że niektóre zespoły związane Mieszanka pozwala zrobić coś takiego w Silverlight i wymyśliłem coś takiego, w którym mam następujące przestrzenie nazw oświadczył:Silverlight DataTrigger nie uruchamia się na ładowaniu

xmlns:ia="clr-namespace:Microsoft.Expression.Interactivity.Core;assembly=Microsoft.Expression.Interactions" 
xmlns:iv="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity" 


<DataTemplate x:Key="testItemTemplate"> 
     <StackPanel Orientation="Horizontal"> 
      <TextBox Text="{Binding Name, Mode=TwoWay}" x:Name="thing"/>     
      <iv:Interaction.Triggers> 
       <ia:DataTrigger Binding="{Binding Name}" Value="ReddenMe" Comparison="Equal"> 
        <ia:ChangePropertyAction TargetName="thing" PropertyName="Foreground" Value="Red"> 
        </ia:ChangePropertyAction> 
       </ia:DataTrigger> 
      </iv:Interaction.Triggers> 
     </StackPanel> 
    </DataTemplate> 

W tym przykładzie, otrzymałem obiekt danych wdrażający INotifyPropertyChanged i jak zwykle podnoszenie zdarzenia PropertyChanged dla właściwości Name. Dostaję oczekiwane zachowanie, jeśli zmienię wartość pola tekstowego i utracę ostrość, ale jeśli wartość początkowa pola tekstowego zostanie ustawiona na ReddenMe (co dla tego wymyślonego przykładu używam jako wyzwalacza dla tekstu, który ma być czerwony), tekst nie zmienia koloru na czerwony. Czy ktoś wie, co się tutaj dzieje? W przypadku funkcji DataTrigger w WPF wyzwalacz zostanie natychmiast uruchomiony w przypadku jakichkolwiek danych.

Zdaję sobie sprawę, że mogę użyć konwertera tutaj, ale mogę wymyślić sytuacje, w których chciałbym użyć wyzwalaczy, i zastanawiam się, czy jest coś, co mógłbym zrobić, aby to zadziałało.

+0

Hi ... przetestowaniu dylemat i mam ten sam problem. Niestety tak się dzieje, kiedy, jak ty, przechodzimy z WPF do Silverlight i poniżej: o (Nie wiem, czy istnieje rozwiązanie, ale stworzyłem konwerter do wykonania zadania i zadziałało to z wartościami początkowymi. – NestorArturo

+0

dla tego NestorArturo: tak, po tym, jak to napisałem, próbowałem osiągnąć to samo z konwerterem, i wydawało mi się, że robię to, co robiłem. Byłoby interesujące usłyszeć, co każdy guru WPF/Silverlight myśli o zaletach oddzielnych konwerterów w porównaniu do czysto opartych na XAML podejść Do rzeczy takich jak pokazywanie/ukrywanie kontrolek, zawsze uważałem podejście DataTrigger za nieco bardziej przejrzyste, chociaż przypuszczam, że można argumentować, że mając konwerter, otrzymujesz mniej zagracone znacznik na końcu: – andrewmcc

+0

Możesz zobaczyć to zachowanie, ponieważ DataTrigger pochodzi z właściwości PropertyChangeTrigger, aw twoim przypadku właściwość Name nie zmienia się początkowo lub może to być błąd.Możesz użyć reflektora .net do przejrzenia w DataTri Implementacja ggera do potwierdzenia. Używam DataTriggers wcześniej, ale nie mam do czynienia z tym problemem prawdopodobnie ze względu na fakt, że używam wizualnego menedżera stanu i zaczynam od stanu domyślnego. Jednym ze sposobów, w jaki można wymusić pożądane zachowanie, jest ustawienie wartości Nazwa po załadowaniu XAML. – Denis

Odpowiedz

11

Oto a solution Znalazłem na blogu Toma Peplowa: dziedziczę z DataTrigger i ustaw wyzwalacz, aby ocenić stan, gdy załadowany zostanie powiązany z nim element.

Oto w jaki sposób można go zakodować:

public class DataTriggerEvaluateOnLoad : Microsoft.Expression.Interactivity.Core.DataTrigger 
{ 
    protected override void OnAttached() 
    { 
     base.OnAttached(); 
     var element = AssociatedObject as FrameworkElement; 
     if (element != null) 
     { 
      element.Loaded += OnElementLoaded; 
     } 
    } 

    protected override void OnDetaching() 
    { 
     base.OnDetaching(); 
     var element = AssociatedObject as FrameworkElement; 
     if (element != null) 
     { 
      element.Loaded -= OnElementLoaded; 
     } 
    } 

    private void OnElementLoaded(object sender, RoutedEventArgs e) 
    { 
     EvaluateBindingChange(null); 
    } 
} 
+0

Dzięki! Walczyłem z tym dzisiaj. – Aligned

+0

To jest takie przydatne ... – Craig

Powiązane problemy