views:

692

answers:

3

I'm having a hard time even phrasing this question.

I'm displaying preview images to users in my UI within a ListBox. When a user hovers over the image, I'd like to expand it so the user can see more detail.

I've gotten to the point where I can "pop up" the image, but of course it is still within its normal position in the layout, meaning that rather than the image being displayed on top of the other controls near it, it only appears on top of the controls rendered before it and underneath those rendered after it. It is also being cropped by the bounds of the ListBox.

Is there a simple (i.e., no custom control development) way to, temporarily, remove that image from the visual layout and put it above all other elements?

Here's a crappy demo app that shows what I'm talking about:

Demonstration of issues

Notice the zoomed image is clipped by the bounds of the ListBox (outside of the list box is red). Also, notice that UI elements rendered after the zoomed image overlay it still--both icons that come later and item names ("Item 5" and others seen in the lower left hand corner).

+2  A: 

This effect is frequently referred to as Fisheye. You may have better luck searching for resources using that term. Here is one sample. http://www.codeproject.com/KB/menus/FishEyeMenu.aspx

regentgal
+3  A: 

If you are looking for something simple, you could also create a tooltip for the image (or ListBoxItem) that contains the larger version of the image. It will be displayed just like a normal tooltip when the user hovers over the smaller version of the image. Here is an example:

<Image Width="100">
    <Image.Source>
        <BitmapImage UriSource="pack://application:,,/smiley.jpg"/>
    </Image.Source>
    <Image.ToolTip>
        <Image Width="500">
            <Image.Source>
                <BitmapImage UriSource="pack://application:,,/smiley.jpg"/>
            </Image.Source>
        </Image>
    </Image.ToolTip>
</Image>

The effect is similar to what you describe, except the menu item is still there but there is also a larger version of it shown, like this:

alt text

Ben Collier
Dude... AWESOME. Going to try this one out now.
Will
+1  A: 

The solution which worked best for me was using the Popup primitive. It doesn't provide much in the way of control when it comes to animation (it comes with stock animations) but you can animate its contents any which way you like.

<Image
    Name="icon"
    Source="{Binding MaiImaeg}">
  <Image.Triggers>
    <EventTrigger
        RoutedEvent="Image.MouseEnter">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimation
              Storyboard.TargetName="tranny"
              Storyboard.TargetProperty="ScaleX"
              To="6"
              Duration="0:0:1">
            <DoubleAnimation.EasingFunction>
              <ElasticEase
                  Oscillations="1"
                  Springiness="8" />
            </DoubleAnimation.EasingFunction>
          </DoubleAnimation>
          <DoubleAnimation
              Storyboard.TargetName="tranny"
              Storyboard.TargetProperty="ScaleY"
              To="6"
              Duration="0:0:1">
            <DoubleAnimation.EasingFunction>
              <ElasticEase
                  Oscillations="1"
                  Springiness="8" />
            </DoubleAnimation.EasingFunction>
          </DoubleAnimation>
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
    <EventTrigger
        RoutedEvent="Image.MouseLeave">
      <BeginStoryboard>
        <Storyboard>
          <DoubleAnimation
              Storyboard.TargetName="tranny"
              Storyboard.TargetProperty="ScaleX"
              To="0"
              Duration="0:0:0" />
          <DoubleAnimation
              Storyboard.TargetName="tranny"
              Storyboard.TargetProperty="ScaleY"
              To="0"
              Duration="0:0:0" />
        </Storyboard>
      </BeginStoryboard>
    </EventTrigger>
  </Image.Triggers>
</Image>
<Popup
    Name="popup"
    IsOpen="{Binding IsMouseOver, ElementName=icon, Mode=OneWay}"
    PlacementTarget="{Binding ElementName=icon}"
    Placement="Left"
    Width="640"
    Height="640"
    StaysOpen="true"
    AllowsTransparency="True">
    <Image
       Width="48"
       Height="48"
       Source="{Binding MaiImaeg}">
       <Image.RenderTransform>
           <ScaleTransform
                x:Name="tranny"
                CenterX="48"
                CenterY="24"
                ScaleX="1"
                ScaleY="1" />
        </Image.RenderTransform>
    </Image>
</Popup>

In this snippet, the popup is not open until IsMouseOver is true for its Image (named "icon"). When the mouse enters the image, two things happen. The Popup opens (at 640x640) and an image is shown (48px by 48px). This image has a scale transform on it. The "icon" Image also has a storyboard for MouseEnter and MouseLeave. This storyboard uses a double animation, targeted at the popup image's ScaleTransform. This storyboard enlarges the image when the mouse enters and shrinks it when it leaves with a nice easing function.

The use case would be: "User is presented a listbox with small images for each item in the list. When the user hovers over the small image (icon), it springs forward and enlarges, giving the user a better view of the image. When the mouse leaves the image, it shrinks back to its original size."

Will