2011-08-19 101 views
2

我希望能够在后台维护一个列表,将新项目放在列表的末尾(以避免Insert()将项目推到更新上),但是能够显示它没有“排序”的相反顺序。WPF查看列表查看后退

我只是希望它在列表视图中以相反顺序出现在列表中。我可以用模板或类似的东西做到这一点吗?

回答

0

这样的事情?

public ObservableCollection<Type> ListBeingMaintained { get; set; } 

    public ObservableCollection<Type> ListBeingDisplayed { get; set; } 

    public MainWindow() 
    { 
     ListBeingMaintained = new ObservableCollection<Type>(GetItems()); 
     ListBeingMaintained.CollectionChanged += new System.Collections.Specialized.NotifyCollectionChangedEventHandler(ListBeingMaintained_CollectionChanged); 

     InitializeComponent(); 
    } 

    private void ListBeingMaintained_CollectionChanged(object sender, System.Collections.Specialized.NotifyCollectionChangedEventArgs e) 
    { 
     List<Type> reversedList = new List<Type>(ListBeingMaintained); 

     reversedList.Reverse(); 

     ListBeingDisplayed = new ObservableCollection<Type>(reversedList); 
    } 

所以基本上你有两个列表,其中一个您的控件绑定到一个和你正在维护(即加入)。你有一个处理集合改变的事件,所以你会收到通知,当项目被添加等,然后你采取维护列表并将其逆转。

+0

这听起来像一个坏主意,开销太大...... –

+0

确实有一定的开销,但不知道该如何实现他想要的东西不排序(这是我'd)。 –

+0

任何绑定到ListBeingDisplayed的东西在每次更改ListBeingMaintaned时都会失去其引用(同样,您拼错保持)。这是因为ListBeingDisplayed每次都会成为一个新列表。最好插入集合的前面。是的,没有*一些*开销没有办法做到这一点... –

4

更新
下面是一个附加的行为,这将逆转任何ItemsControl。使用这样的

<ListBox behaviors:ReverseItemsControlBehavior.ReverseItemsControl="True" 
     ...> 

ReverseItemsControlBehavior

public class ReverseItemsControlBehavior 
{ 
    public static DependencyProperty ReverseItemsControlProperty = 
     DependencyProperty.RegisterAttached("ReverseItemsControl", 
              typeof(bool), 
              typeof(ReverseItemsControlBehavior), 
              new FrameworkPropertyMetadata(false, OnReverseItemsControlChanged)); 
    public static bool GetReverseItemsControl(DependencyObject obj) 
    { 
     return (bool)obj.GetValue(ReverseItemsControlProperty); 
    } 
    public static void SetReverseItemsControl(DependencyObject obj, object value) 
    { 
     obj.SetValue(ReverseItemsControlProperty, value); 
    } 

    private static void OnReverseItemsControlChanged(object sender, DependencyPropertyChangedEventArgs e) 
    { 
     if ((bool)e.NewValue == true) 
     { 
      ItemsControl itemsControl = sender as ItemsControl; 
      if (itemsControl.IsLoaded == true) 
      { 
       DoReverseItemsControl(itemsControl); 
      } 
      else 
      { 
       RoutedEventHandler loadedEventHandler = null; 
       loadedEventHandler = (object sender2, RoutedEventArgs e2) => 
       { 
        itemsControl.Loaded -= loadedEventHandler; 
        DoReverseItemsControl(itemsControl); 
       }; 
       itemsControl.Loaded += loadedEventHandler; 
      } 
     } 
    } 
    private static void DoReverseItemsControl(ItemsControl itemsControl) 
    { 
     Panel itemPanel = GetItemsPanel(itemsControl); 
     itemPanel.LayoutTransform = new ScaleTransform(1, -1); 
     Style itemContainerStyle; 
     if (itemsControl.ItemContainerStyle == null) 
     { 
      itemContainerStyle = new Style(); 
     } 
     else 
     { 
      itemContainerStyle = CopyStyle(itemsControl.ItemContainerStyle); 
     } 
     Setter setter = new Setter(); 
     setter.Property = ItemsControl.LayoutTransformProperty; 
     setter.Value = new ScaleTransform(1, -1); 
     itemContainerStyle.Setters.Add(setter); 
     itemsControl.ItemContainerStyle = itemContainerStyle; 
    } 
    private static Panel GetItemsPanel(ItemsControl itemsControl) 
    { 
     ItemsPresenter itemsPresenter = GetVisualChild<ItemsPresenter>(itemsControl); 
     if (itemsPresenter == null) 
      return null; 
     return GetVisualChild<Panel>(itemsControl); 
    } 
    private static Style CopyStyle(Style style) 
    { 
     Style styleCopy = new Style(); 
     foreach (SetterBase currentSetter in style.Setters) 
     { 
      styleCopy.Setters.Add(currentSetter); 
     } 
     foreach (TriggerBase currentTrigger in style.Triggers) 
     { 
      styleCopy.Triggers.Add(currentTrigger); 
     } 
     return styleCopy; 
    } 

    private static T GetVisualChild<T>(DependencyObject parent) where T : Visual 
    { 
     T child = default(T); 

     int numVisuals = VisualTreeHelper.GetChildrenCount(parent); 
     for (int i = 0; i < numVisuals; i++) 
     { 
      Visual v = (Visual)VisualTreeHelper.GetChild(parent, i); 
      child = v as T; 
      if (child == null) 
      { 
       child = GetVisualChild<T>(v); 
      } 
      if (child != null) 
      { 
       break; 
      } 
     } 
     return child; 
    } 
} 

否则,你可以关注你在下面的链接概述:WPF reverse ListView

<ListBox ...> 
    <ListBox.ItemsPanel> 
     <ItemsPanelTemplate> 
      <VirtualizingStackPanel VerticalAlignment="Top" Orientation="Vertical"> 
       <VirtualizingStackPanel.LayoutTransform> 
        <ScaleTransform ScaleX="1" ScaleY="-1" /> 
       </VirtualizingStackPanel.LayoutTransform> 
      </VirtualizingStackPanel> 
     </ItemsPanelTemplate> 
    </ListBox.ItemsPanel> 
    <ListBox.ItemContainerStyle> 
     <Style TargetType="ListBoxItem"> 
      <Setter Property="LayoutTransform"> 
       <Setter.Value> 
        <ScaleTransform ScaleX="1" ScaleY="-1" /> 
       </Setter.Value> 
      </Setter> 
     </Style> 
    </ListBox.ItemContainerStyle> 
</ListBox> 
+0

链接中的第二个代码块(用于listview)使项目颠倒。代码的第一部分似乎不适用于收集更改(以我的经验)。 –

+0

第二个块为我工作(首先不能在设计模式下工作)。您需要应用两种ScaleTransforms。第一个将显示他整个堆叠面板颠倒(与反向项目)和第二个变换你只是恢复每个项目 – Florian

0

您可以更改ListView的ItemsPanel成为带Last的DockPanel ChildFill设置为false。然后在ItemContainerStyle中,将DockPanel.Dock属性设置为底部。这将开始填补底部,并一直工作到顶部。我把ListView放在一个有2行的网格中,第一个是Height =“Auto”,第二个是Height =“*”,它的作用与普通的ListView相似,但是项目相反。取自

<Grid> 
    <Grid.RowDefinitions> 
     <RowDefinition Height="Auto" /> 
     <RowDefinition Height="*" /> 
    </Grid.RowDefinitions> 
    <ListBox Grid.Row="0"> 
    <ListBox.ItemContainerStyle> 
      <Style TargetType="{x:Type ListBoxItem}" 
        BasedOn="{StaticResource {x:Type ListBoxItem}}"> 
       <Setter Property="DockPanel.Dock" 
         Value="Bottom" /> 
      </Style> 
     </ListBox.ItemContainerStyle> 
     <ListBox.ItemsPanel> 
      <ItemsPanelTemplate> 
       <DockPanel LastChildFill="False" /> 
      </ItemsPanelTemplate> 
     </ListBox.ItemsPanel> 
    </ListBox> 
</Grid> 

理念: https://stackoverflow.com/a/493059/2812277