none
FluidMoveBehavior 4 problem in WPF

    Question

  • I tried to replicate the list to list fluidmovebehavior from this sample in WPF: http://gallery.expression.microsoft.com/en-us/DynamicLayoutTrans.

    In WPF however the item shows up in the list for a moment before it gets fluidmove animated into the listbox resulting a kind of "blink" effect. Does that have to do with WPF 4 missing layout states and if so what alternatives could I use to get it working properly?

    Sunday, July 18, 2010 12:32 PM

Answers

  • Hi there,

    Yes, unfortunately this is a known bug with that behavior that we would like to fix. In the meantime, I was told of a workaround that you might be able to use. Please let us know if it works for you or not.

    a) Add this custom behavior to your project

    namespace WpfApplication2
    {
     public class InvalidateListBoxItemAfterLoadBehavior : Behavior<FrameworkElement>
     {
      public InvalidateListBoxItemAfterLoadBehavior()
      {
      }

      protected override void OnAttached()
      {
       base.OnAttached();
       
       this.AssociatedObject.Loaded += AssociatedObject_Loaded;
      }

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

      private void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
      {
       FrameworkElement ancestor = this.AssociatedObject;
       
       while (ancestor != null)
       {
        if (ancestor is ListBoxItem)
        {
         ancestor.InvalidateArrange();
         return;
        }
        ancestor = VisualTreeHelper.GetParent(ancestor) as FrameworkElement;
       }
      }
     }
    }

    b) Update your XAML to use this behavior:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:local="clr-namespace:WpfApplication2" x:Class="WpfApplication2.MainWindow"
            Title="MainWindow" Height="350" Width="525">
       
        <Window.Resources>
         <ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
          <StackPanel>
           <i:Interaction.Behaviors>
            <ei:FluidMoveBehavior Duration="0:0:0.5" AppliesTo="Children" Tag="DataContext">
             <ei:FluidMoveBehavior.EaseY>
              <BackEase EasingMode="EaseInOut"/>
             </ei:FluidMoveBehavior.EaseY>
             <ei:FluidMoveBehavior.EaseX>
              <BackEase EasingMode="EaseInOut"/>
             </ei:FluidMoveBehavior.EaseX>
            </ei:FluidMoveBehavior>
           </i:Interaction.Behaviors>
          </StackPanel>
         </ItemsPanelTemplate>
        </Window.Resources>
       
        <Grid x:Name="LayoutRoot" Background="White">
            <StackPanel Orientation="Horizontal">
                <ListBox x:Name="ListA" Width="100" Margin="5"
                         ItemsSource="{Binding}" SelectionChanged="ListA_SelectionChanged" ItemsPanel="{DynamicResource ItemsPanelTemplate1}" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}">
                             <i:Interaction.Behaviors>
                              <local:InvalidateListBoxItemAfterLoadBehavior/>
                             </i:Interaction.Behaviors>
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <ListBox x:Name="ListB" Width="100" Margin="5"
                         ItemsSource="{Binding}" SelectionChanged="ListB_SelectionChanged" ItemsPanel="{DynamicResource ItemsPanelTemplate1}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}">
                             <i:Interaction.Behaviors>
                              <local:InvalidateListBoxItemAfterLoadBehavior/>
                             </i:Interaction.Behaviors>
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </Window>


    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Marked as answer by DVSBSTD Tuesday, July 20, 2010 4:43 AM
    Tuesday, July 20, 2010 1:43 AM

All replies

  • Hi there,

    Yes, unfortunately this is a known bug with that behavior that we would like to fix. In the meantime, I was told of a workaround that you might be able to use. Please let us know if it works for you or not.

    a) Add this custom behavior to your project

    namespace WpfApplication2
    {
     public class InvalidateListBoxItemAfterLoadBehavior : Behavior<FrameworkElement>
     {
      public InvalidateListBoxItemAfterLoadBehavior()
      {
      }

      protected override void OnAttached()
      {
       base.OnAttached();
       
       this.AssociatedObject.Loaded += AssociatedObject_Loaded;
      }

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

      private void AssociatedObject_Loaded(object sender, System.Windows.RoutedEventArgs e)
      {
       FrameworkElement ancestor = this.AssociatedObject;
       
       while (ancestor != null)
       {
        if (ancestor is ListBoxItem)
        {
         ancestor.InvalidateArrange();
         return;
        }
        ancestor = VisualTreeHelper.GetParent(ancestor) as FrameworkElement;
       }
      }
     }
    }

    b) Update your XAML to use this behavior:

    <Window
            xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
            xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
            xmlns:ei="http://schemas.microsoft.com/expression/2010/interactions"
            xmlns:i="http://schemas.microsoft.com/expression/2010/interactivity"
            xmlns:local="clr-namespace:WpfApplication2" x:Class="WpfApplication2.MainWindow"
            Title="MainWindow" Height="350" Width="525">
       
        <Window.Resources>
         <ItemsPanelTemplate x:Key="ItemsPanelTemplate1">
          <StackPanel>
           <i:Interaction.Behaviors>
            <ei:FluidMoveBehavior Duration="0:0:0.5" AppliesTo="Children" Tag="DataContext">
             <ei:FluidMoveBehavior.EaseY>
              <BackEase EasingMode="EaseInOut"/>
             </ei:FluidMoveBehavior.EaseY>
             <ei:FluidMoveBehavior.EaseX>
              <BackEase EasingMode="EaseInOut"/>
             </ei:FluidMoveBehavior.EaseX>
            </ei:FluidMoveBehavior>
           </i:Interaction.Behaviors>
          </StackPanel>
         </ItemsPanelTemplate>
        </Window.Resources>
       
        <Grid x:Name="LayoutRoot" Background="White">
            <StackPanel Orientation="Horizontal">
                <ListBox x:Name="ListA" Width="100" Margin="5"
                         ItemsSource="{Binding}" SelectionChanged="ListA_SelectionChanged" ItemsPanel="{DynamicResource ItemsPanelTemplate1}" >
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}">
                             <i:Interaction.Behaviors>
                              <local:InvalidateListBoxItemAfterLoadBehavior/>
                             </i:Interaction.Behaviors>
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
                <ListBox x:Name="ListB" Width="100" Margin="5"
                         ItemsSource="{Binding}" SelectionChanged="ListB_SelectionChanged" ItemsPanel="{DynamicResource ItemsPanelTemplate1}">
                    <ListBox.ItemTemplate>
                        <DataTemplate>
                            <TextBlock Text="{Binding Name}">
                             <i:Interaction.Behaviors>
                              <local:InvalidateListBoxItemAfterLoadBehavior/>
                             </i:Interaction.Behaviors>
                            </TextBlock>
                        </DataTemplate>
                    </ListBox.ItemTemplate>
                </ListBox>
            </StackPanel>
        </Grid>
    </Window>


    This posting is provided "AS IS" with no warranties, and confers no rights.
    • Marked as answer by DVSBSTD Tuesday, July 20, 2010 4:43 AM
    Tuesday, July 20, 2010 1:43 AM
  • That worked perfectly, thanks!
    Tuesday, July 20, 2010 4:43 AM
  • Just found this which solved my problem also!

    Many thanks Unni!

    Tuesday, August 30, 2011 12:00 PM