locked
How to customize a list box ? RRS feed

  • Question

  • Dear all,

    I have a list box which is actually style in order to display listbox items as a set of pictures with a title.
    When using the List box I can scroll my list either vertically or horizontaly depending on my settings.

    Actually the default behaviour of a list box is that items scrolling ocurs in a straigth direction horizital or vertical following a kind of straigth line.

    Lets imagine that I can select in design mode the listbox border and make it as an arc, then beeing able to scroll my items which folow that arc path.

    Is tehre a way to do this ?

    regards
    Serge


    Your knowledge is enhanced by that of others.
    Tuesday, July 27, 2010 10:32 AM

Answers

  • Hi Serge,

    Yes, it can.

    The default ItemPanel of the ListBox is a StackPanel that only allows to scroll the items in a vertical or horizontal direction. However, we can change it to other panels through ListBox.ItemsPanel property, such as Grid panel, WrapPanel.

     <ListBox>
      <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
       ....
      </ItemsPanelTemplate>
      </ListBox.ItemsPanel>
     </ListBox>
    

    Of cause, we can create a custom panel to arrange the item as a arc or a circle, please refer to http://msdn.microsoft.com/en-us/library/ms754152.aspx#Panels_custom_panel_elements to know more about the custom panel in WPF. And I answered below thread is about to implement a circle panel may help you: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c38571cb-db38-429a-942d-ce738fc1bfd2

    I modify the CirclePanel to a ArcPanel, below is a sample that set this panel to the ItemPanel of the ListBox: http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100728%5E_ArcPanelInListBox.zip

    And below is a diagram which can explain the panel:

     

    Hope this helps.

    Sincerely,

    Bob Bao

    MSDN Subscriber Support in Forum 

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Edited by Jie Bao Thursday, July 29, 2010 3:03 PM
    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Wednesday, July 28, 2010 5:22 AM
  • In addition to Bob's reply, you could also use PathListBox (new in WPF/SL 4).  It requires the Blend controls but it is very very cool.

    One of the WPF Disciples takes it for a test drive:

    http://sachabarber.net/?p=733

    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Wednesday, July 28, 2010 5:53 AM
  • Hi Serge,

    I made a mistake in the diagram that all items should fill the gray area range between the Angle. I have updated the diagram, please check agian.

    1- If Items are pictures tumnail, will theu automatically fit in thegray area ?

    Yes, all items will fill the gray area in the uniform distribution mode.

    2- What I am trying to reach is by selecting an item wby holding down the mouse ( let say item 1 in your drawing) and then moving the mouse to the position of Item 6 , then I should be able to scroll down the all list of item. Then Item 1 will be at the palce of item 6 and all others items will be then moved down to the bottom part of the circle. During that I would like to apply a small scall transform in order to have far items smaller that closest item in a similar way as a Carousel does .

    We can override the OnPreviewMouseLeftButtonDown, OnMouseLeftButtonUp, OnMouseMove methods to implement this function. We need to calculate the mouse position and update the StartAngle property when the mouse is moving. Please download my sample and run, we can drag the items and the panel can be rotated.

    http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100729%5E_ArcPanelInListBoxWithDrag.zip

    By the way, you could try to use the solution BryanCC provides: http://sachabarber.net/?p=733 That may help you too.

     

    Sincerely,

    Bob Bao

    MSDN Subscriber Support in Forum 

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Thursday, July 29, 2010 3:16 PM
  • Hi Serge,

    Thank you for your reply!

    Q:What about the way of having this Zoom in and out effect while scrolling items ?

    We can zoom the element by a transform - ScaleTransform. Such as, we can declare a animation for the item and when the mouse over the item, zoom out the item image:

      <ListBox.ItemContainerStyle>
      <Style TargetType="{x:Type ListBoxItem}">
       <Setter Property="LayoutTransform">
       <Setter.Value>
        <ScaleTransform CenterX="0.5" CenterY="0.5"/>
       </Setter.Value>
       </Setter>
       <Style.Triggers>
       <EventTrigger RoutedEvent="MouseEnter">
        <BeginStoryboard>
        <Storyboard>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:.2"/>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:.2"/>
        </Storyboard>
        </BeginStoryboard>
       </EventTrigger>
       <EventTrigger RoutedEvent="MouseLeave">
        <BeginStoryboard>
        <Storyboard>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleX)" To="1" Duration="0:0:.2"/>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleY)" To="1" Duration="0:0:.2"/>
        </Storyboard>
        </BeginStoryboard>
       </EventTrigger>
       </Style.Triggers>
      </Style>
      </ListBox.ItemContainerStyle>
    

    Q:strangebehaviour happen when you hold the mouse on an Iem in the middle, let say Item 4 and start to move then is select by default item 1 ?

    Since my drag algorithm calculates the current mouse position and set the SatrtAngle to the current angle, so we alway drag the item 1 element; Even if the mouse start to drag at the middle of the list.

     

    Of cause, we can change it , that should remeber the drag start position and calculate the offset between the current mouse angle and the start mouse angle. Then change the StartAngle variable:

    Such as:

     #region Private Properties
     private bool IsMouseLeftButtonPressed = false;
     double StartPositionAngle;
     #endregion
     ......
     protected override void OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
     {
      IsMouseLeftButtonPressed = true;
      Point MouseStartPosition = e.GetPosition(this);
      StartPositionAngle = RadianToAngle(Math.Atan((MouseStartPosition.X - OuterRadius) / (MouseStartPosition.Y - OuterRadius))) -
           StartAngle + (MouseStartPosition.Y >= OuterRadius ? 1 : 0) * 180;
      this.Cursor = Cursors.Hand;
      base.OnPreviewMouseLeftButtonDown(e);
     }
    
     protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)
     {
      IsMouseLeftButtonPressed = false;
      this.Cursor = Cursors.Arrow;
      base.OnMouseLeftButtonUp(e);
     }
    
     protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
     {
      if (IsMouseLeftButtonPressed)
      {
      Point CurrentPosition = e.GetPosition(this);
      if (CurrentPosition.Y == OuterRadius)
       CurrentPositionAngle = 90.0;
      else
       CurrentPositionAngle = RadianToAngle(Math.Atan((CurrentPosition.X - OuterRadius) / (CurrentPosition.Y - OuterRadius)));
    
      StartAngle = (IsClockwise ? -1 : 1) * (CurrentPositionAngle - StartPositionAngle) +
          (CurrentPosition.Y >= OuterRadius ? 1 : 0) * 180;
    
      InvalidateVisual();
      }
      base.OnMouseMove(e);
     }
    

    Updated sample: http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100730%5E_ArcPanelInListBoxWithDrag%5E_Update.zip

    Hope this helps.

    Sincerely,

    Bob Bao


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Friday, July 30, 2010 3:35 AM

All replies

  • Hi Serge,

    Yes, it can.

    The default ItemPanel of the ListBox is a StackPanel that only allows to scroll the items in a vertical or horizontal direction. However, we can change it to other panels through ListBox.ItemsPanel property, such as Grid panel, WrapPanel.

     <ListBox>
      <ListBox.ItemsPanel>
      <ItemsPanelTemplate>
       ....
      </ItemsPanelTemplate>
      </ListBox.ItemsPanel>
     </ListBox>
    

    Of cause, we can create a custom panel to arrange the item as a arc or a circle, please refer to http://msdn.microsoft.com/en-us/library/ms754152.aspx#Panels_custom_panel_elements to know more about the custom panel in WPF. And I answered below thread is about to implement a circle panel may help you: http://social.msdn.microsoft.com/Forums/en-US/wpf/thread/c38571cb-db38-429a-942d-ce738fc1bfd2

    I modify the CirclePanel to a ArcPanel, below is a sample that set this panel to the ItemPanel of the ListBox: http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100728%5E_ArcPanelInListBox.zip

    And below is a diagram which can explain the panel:

     

    Hope this helps.

    Sincerely,

    Bob Bao

    MSDN Subscriber Support in Forum 

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Edited by Jie Bao Thursday, July 29, 2010 3:03 PM
    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Wednesday, July 28, 2010 5:22 AM
  • In addition to Bob's reply, you could also use PathListBox (new in WPF/SL 4).  It requires the Blend controls but it is very very cool.

    One of the WPF Disciples takes it for a test drive:

    http://sachabarber.net/?p=733

    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Wednesday, July 28, 2010 5:53 AM
  • Hello bob, thnaks for your post

    I have try your sample and this is what I am looking for but then what I try to apply from your sample is the following.

    1- If Items are pictures tumnail, will theu automatically fit in thegray area ?

    2- What I am trying to reach is by selecting an item wby holding down the mouse ( let say item 1 in your drawing) and then moving the mouse to the position of Item 6 , then I should be able to scroll down the all list of item. Then Item 1 will be at the palce of item 6 and all others items will be then moved down to the bottom part of the circle. During that I would like to apply a small scall transform in order to have far items smaller that closest item in a similar way as a Carousel does .

    How can I apply this starting from your sample ?

    Thnaks for help
    regards

    Serge


    Your knowledge is enhanced by that of others.
    Thursday, July 29, 2010 11:35 AM
  • Hi Serge,

    I made a mistake in the diagram that all items should fill the gray area range between the Angle. I have updated the diagram, please check agian.

    1- If Items are pictures tumnail, will theu automatically fit in thegray area ?

    Yes, all items will fill the gray area in the uniform distribution mode.

    2- What I am trying to reach is by selecting an item wby holding down the mouse ( let say item 1 in your drawing) and then moving the mouse to the position of Item 6 , then I should be able to scroll down the all list of item. Then Item 1 will be at the palce of item 6 and all others items will be then moved down to the bottom part of the circle. During that I would like to apply a small scall transform in order to have far items smaller that closest item in a similar way as a Carousel does .

    We can override the OnPreviewMouseLeftButtonDown, OnMouseLeftButtonUp, OnMouseMove methods to implement this function. We need to calculate the mouse position and update the StartAngle property when the mouse is moving. Please download my sample and run, we can drag the items and the panel can be rotated.

    http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100729%5E_ArcPanelInListBoxWithDrag.zip

    By the way, you could try to use the solution BryanCC provides: http://sachabarber.net/?p=733 That may help you too.

     

    Sincerely,

    Bob Bao

    MSDN Subscriber Support in Forum 

    If you have any feedback on our support, please contact msdnmg@microsoft.com


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Thursday, July 29, 2010 3:16 PM
  • I am using Blend 2.0 still in my project so i guess I cannot use what bryan suggest.

    What about the way of having this Zoom in and out effect while scrolling items bob ?

    thnaks so much for your help


    Your knowledge is enhanced by that of others.
    Thursday, July 29, 2010 3:54 PM
  • strangebehaviour happen when you hold the mouse on an Iem in the middle, let say Item 4 and start to move then is select by default item 1 ??

    regards

    serge


    Your knowledge is enhanced by that of others.
    Thursday, July 29, 2010 4:02 PM
  • Hi Serge,

    Thank you for your reply!

    Q:What about the way of having this Zoom in and out effect while scrolling items ?

    We can zoom the element by a transform - ScaleTransform. Such as, we can declare a animation for the item and when the mouse over the item, zoom out the item image:

      <ListBox.ItemContainerStyle>
      <Style TargetType="{x:Type ListBoxItem}">
       <Setter Property="LayoutTransform">
       <Setter.Value>
        <ScaleTransform CenterX="0.5" CenterY="0.5"/>
       </Setter.Value>
       </Setter>
       <Style.Triggers>
       <EventTrigger RoutedEvent="MouseEnter">
        <BeginStoryboard>
        <Storyboard>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleX)" To="1.5" Duration="0:0:.2"/>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleY)" To="1.5" Duration="0:0:.2"/>
        </Storyboard>
        </BeginStoryboard>
       </EventTrigger>
       <EventTrigger RoutedEvent="MouseLeave">
        <BeginStoryboard>
        <Storyboard>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleX)" To="1" Duration="0:0:.2"/>
         <DoubleAnimation Storyboard.TargetProperty="(LayoutTransform).(ScaleTransform.ScaleY)" To="1" Duration="0:0:.2"/>
        </Storyboard>
        </BeginStoryboard>
       </EventTrigger>
       </Style.Triggers>
      </Style>
      </ListBox.ItemContainerStyle>
    

    Q:strangebehaviour happen when you hold the mouse on an Iem in the middle, let say Item 4 and start to move then is select by default item 1 ?

    Since my drag algorithm calculates the current mouse position and set the SatrtAngle to the current angle, so we alway drag the item 1 element; Even if the mouse start to drag at the middle of the list.

     

    Of cause, we can change it , that should remeber the drag start position and calculate the offset between the current mouse angle and the start mouse angle. Then change the StartAngle variable:

    Such as:

     #region Private Properties
     private bool IsMouseLeftButtonPressed = false;
     double StartPositionAngle;
     #endregion
     ......
     protected override void OnPreviewMouseLeftButtonDown(System.Windows.Input.MouseButtonEventArgs e)
     {
      IsMouseLeftButtonPressed = true;
      Point MouseStartPosition = e.GetPosition(this);
      StartPositionAngle = RadianToAngle(Math.Atan((MouseStartPosition.X - OuterRadius) / (MouseStartPosition.Y - OuterRadius))) -
           StartAngle + (MouseStartPosition.Y >= OuterRadius ? 1 : 0) * 180;
      this.Cursor = Cursors.Hand;
      base.OnPreviewMouseLeftButtonDown(e);
     }
    
     protected override void OnMouseLeftButtonUp(System.Windows.Input.MouseButtonEventArgs e)
     {
      IsMouseLeftButtonPressed = false;
      this.Cursor = Cursors.Arrow;
      base.OnMouseLeftButtonUp(e);
     }
    
     protected override void OnMouseMove(System.Windows.Input.MouseEventArgs e)
     {
      if (IsMouseLeftButtonPressed)
      {
      Point CurrentPosition = e.GetPosition(this);
      if (CurrentPosition.Y == OuterRadius)
       CurrentPositionAngle = 90.0;
      else
       CurrentPositionAngle = RadianToAngle(Math.Atan((CurrentPosition.X - OuterRadius) / (CurrentPosition.Y - OuterRadius)));
    
      StartAngle = (IsClockwise ? -1 : 1) * (CurrentPositionAngle - StartPositionAngle) +
          (CurrentPosition.Y >= OuterRadius ? 1 : 0) * 180;
    
      InvalidateVisual();
      }
      base.OnMouseMove(e);
     }
    

    Updated sample: http://cid-51b2fdd068799d15.office.live.com/self.aspx/.Public/Samples%5E_2010/20100730%5E_ArcPanelInListBoxWithDrag%5E_Update.zip

    Hope this helps.

    Sincerely,

    Bob Bao


    Please remember to mark the replies as answers if they help and unmark them if they provide no help.
    • Marked as answer by Jie Bao Monday, August 9, 2010 1:38 AM
    Friday, July 30, 2010 3:35 AM