tags:

views:

1390

answers:

1

I have the following code snippet (copy and paste into kaxaml, xamlpad, etc to try it) that collapses all but the selected item. However, I want to revert back to all visible when the mouse is not over the ListBox and I just cannot get it to work short of going code behind. I am using the IsMouseOver ListBox property to set selected item properties on the ListBox to attempt to trigger an update but no luck. Any ideas?

<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"&gt;
 <Grid>
      <ListBox
           Name="lb"
           Width="100"
           Height="100"
           Background="Red"
           SelectionMode="Single">
           <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                     <UniformGrid Columns="1"/>
                </ItemsPanelTemplate>
           </ListBox.ItemsPanel>
           <ListBoxItem Background="AliceBlue">Item 1    
           </ListBoxItem>
           <ListBoxItem Background="Aquamarine">Item 
           </ListBoxItem>
           <ListBoxItem Background="Azure">Item 
           </ListBoxItem>
           <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                     <Setter Property="Visibility" Value="Visible"/>
                     <Style.Triggers>
                          <MultiDataTrigger>
                               <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="False"/>
                                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=SelectedItems.Count}" Value="1"/>
                               </MultiDataTrigger.Conditions>
                               <MultiDataTrigger.EnterActions>
                                    <BeginStoryboard>
                                         <Storyboard Duration="0:0:1">
                                              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
                                                   <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Collapsed}"/>
                                              </ObjectAnimationUsingKeyFrames>
                                              <DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Opacity" To="0"/>
                                         </Storyboard>
                                    </BeginStoryboard>
                               </MultiDataTrigger.EnterActions>
                          </MultiDataTrigger>
                          <MultiDataTrigger>
                               <MultiDataTrigger.Conditions>
                                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="True"/>
                                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=SelectedItems.Count}" Value="1"/>
                               </MultiDataTrigger.Conditions>
                               <MultiDataTrigger.EnterActions>
                                    <BeginStoryboard>
                                         <Storyboard Duration="0:0:0">
                                              <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
                                                   <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
                                              </ObjectAnimationUsingKeyFrames>
                                              <DoubleAnimation Duration="0:0:0" Storyboard.TargetProperty="Opacity" To="1"/>
                                         </Storyboard>
                                    </BeginStoryboard>
                               </MultiDataTrigger.EnterActions>
                          </MultiDataTrigger>
                     </Style.Triggers>
                </Style>
           </ListBox.ItemContainerStyle>
           <ListBox.Style>
                <Style>
                     <Style.Triggers>
                          <Trigger Property="ListBox.IsMouseOver" Value="False">
                               <Setter Property="ListBox.SelectedItem" Value="{x:Null}"/>
                               <Setter Property="ListBoxItem.IsSelected" Value="False"/>
                               <Setter Property="ListBox.SelectedIndex" Value="-1"/>
                          </Trigger>
                          <EventTrigger RoutedEvent="Mouse.MouseLeave">
                               <BeginStoryboard>
                                    <Storyboard>
                                         <Int32Animation Duration="0:0:0" Storyboard.TargetProperty="SelectedIndex" To="-1"/>
                                    </Storyboard>
                               </BeginStoryboard>
                          </EventTrigger>
                     </Style.Triggers>
                </Style>
           </ListBox.Style>
      </ListBox>
 </Grid>
</Page>

+2  A: 

Move your style to resources and apply it when the mouse is over the ListBox.`

<Page.Resources>
    <Style x:Key="CustomStyle" TargetType="{x:Type ListBoxItem}">
        <Style.Triggers>
            <MultiDataTrigger>
                <MultiDataTrigger.Conditions>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Self}, Path=IsSelected}" Value="False"/>
                    <Condition Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor,AncestorType={x:Type ListBox}},Path=SelectedItems.Count}" Value="1"/>
                </MultiDataTrigger.Conditions>
                <MultiDataTrigger.EnterActions>
                    <BeginStoryboard>
                        <Storyboard Duration="0:0:1">
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:1" Value="{x:Static Visibility.Collapsed}"/>
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimation Duration="0:0:1" Storyboard.TargetProperty="Opacity" To="0"/>
                        </Storyboard>
                    </BeginStoryboard>
                </MultiDataTrigger.EnterActions>
                <MultiDataTrigger.ExitActions>
                    <BeginStoryboard>
                        <Storyboard Duration="0:0:0">
                            <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Visibility">
                                <DiscreteObjectKeyFrame KeyTime="0:0:0" Value="{x:Static Visibility.Visible}"/>
                            </ObjectAnimationUsingKeyFrames>
                            <DoubleAnimation Duration="0:0:0" Storyboard.TargetProperty="Opacity" To="1"/>
                        </Storyboard>
                    </BeginStoryboard>
                </MultiDataTrigger.ExitActions>
            </MultiDataTrigger>
        </Style.Triggers>
    </Style>
</Page.Resources>

<Grid>
    <ListBox
       Name="lb"
       Width="100"
       Height="100"
       Background="Red"
       SelectionMode="Single">
        <ListBox.ItemsPanel>
            <ItemsPanelTemplate>
                <UniformGrid Columns="1"/>
            </ItemsPanelTemplate>
        </ListBox.ItemsPanel>
        <ListBoxItem Background="AliceBlue">Item 1
        </ListBoxItem>
        <ListBoxItem Background="Aquamarine">Item
        </ListBoxItem>
        <ListBoxItem Background="Azure">Item
        </ListBoxItem>
        <ListBox.Style>
            <Style>
                <Style.Triggers>
                    <Trigger Property="ListBox.IsMouseOver" Value="True">
                        <Setter 
                            Property="ListBox.ItemContainerStyle" 
                            Value="{StaticResource CustomStyle}"/>
                    </Trigger>
                </Style.Triggers>
            </Style>
        </ListBox.Style>
    </ListBox>
</Grid>

` Also note the usage of the MultiDataTrigger.ExitActions, these are the actions to apply when the trigger object becomes inactive.

Dmytro Laptin
Nice solution. Thanks!
HiteshP
I have completed this issue and now I have realized why it works exactly this way :)The reason is that animations have the highest priority when setting dependency properties. So when you have set some properties using an animation and you want to return to the initial values use animation to do that, as was done in the MultiDataTrigger.ExitActions element.
Dmytro Laptin