我希望能够在后台维护一个列表,将新项目放在列表的末尾(以避免Insert()将项目推到更新上),但是能够显示它没有“排序”的相反顺序。WPF查看列表查看后退
我只是希望它在列表视图中以相反顺序出现在列表中。我可以用模板或类似的东西做到这一点吗?
我希望能够在后台维护一个列表,将新项目放在列表的末尾(以避免Insert()将项目推到更新上),但是能够显示它没有“排序”的相反顺序。WPF查看列表查看后退
我只是希望它在列表视图中以相反顺序出现在列表中。我可以用模板或类似的东西做到这一点吗?
这样的事情?
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);
}
所以基本上你有两个列表,其中一个您的控件绑定到一个和你正在维护(即加入)。你有一个处理集合改变的事件,所以你会收到通知,当项目被添加等,然后你采取维护列表并将其逆转。
更新
下面是一个附加的行为,这将逆转任何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>
链接中的第二个代码块(用于listview)使项目颠倒。代码的第一部分似乎不适用于收集更改(以我的经验)。 –
第二个块为我工作(首先不能在设计模式下工作)。您需要应用两种ScaleTransforms。第一个将显示他整个堆叠面板颠倒(与反向项目)和第二个变换你只是恢复每个项目 – Florian
您可以更改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>
这听起来像一个坏主意,开销太大...... –
确实有一定的开销,但不知道该如何实现他想要的东西不排序(这是我'd)。 –
任何绑定到ListBeingDisplayed的东西在每次更改ListBeingMaintaned时都会失去其引用(同样,您拼错保持)。这是因为ListBeingDisplayed每次都会成为一个新列表。最好插入集合的前面。是的,没有*一些*开销没有办法做到这一点... –