我使用MVVM模式。在ViewModel中有属性MaxVisibleItems
。
在视图中:
<ListBox ItemsSource="{Binding Items}" Margin="0 0 0 5"
VirtualizingPanel.VirtualizationMode="Recycling" VirtualizingPanel.IsContainerVirtualizable="True">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
如何通过ViewModel中的MaxVisibleItems
计算ListBox中可见项的数量。这意味着如果有10个项目且MaxVisibleItems为8,则只显示8个项目,并且滚动条滚动到其他项目。这意味着,MaxVisibleItems设置显示项目的控件的最大高度。
谢谢你的帮助!!!
答案 0 :(得分:0)
这是一个非常疯狂的解决方案:
创建一个接口和一个继承自ObservableCollection
的新类,这将允许我们使用转换器计算出应显示的项目数。
public interface ILimitedCollection : IList
{
int MaxViewable { get; set; }
}
public class LimitedObservableCollection<T> : ObservableCollection<T>, ILimitedCollection
{
private int _MaxViewable;
public int MaxViewable
{
get { return _MaxViewable; }
set
{
_MaxViewable = value;
OnPropertyChanged(new System.ComponentModel.PropertyChangedEventArgs("MaxViewable"));
}
}
}
您的馆藏应该继承LimitedObservableCollection
,而不是ObservableCollection
,然后您可以使用以下转化器:
public class LimitedListConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
ILimitedCollection collection = (ILimitedCollection)value;
ObservableCollection<object> items = new ObservableCollection<object>();
for (int i = 0; i < collection.MaxViewable; i++)
{
var item = collection[i];
items.Add(item);
}
return items;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
}
这只会限制要在集合中显示的项目数。
用法:
{Binding YourCollection, Converter={StaticResource LimitedListConverter}}
备注强>
您可能想知道为什么我不只是使用ConverterParameter
。好吧,我可以,但是不可能将ConverterParameter绑定到ViewModel中的属性。因此,更复杂的解决方案就足够了。
这可能不是最佳解决方案,但是,它肯定是一个开始。
答案 1 :(得分:0)
鉴于您知道物品的固定高度,您可以使用以下内容:
public class FixedHeightConverter : IValueConverter
{
// Change to whatever your fixed height is.
const int ItemHeight = 25;
public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
// Note that this currently will display the ListBox with a height of 0 when there are no entries. It would probably be sensible to make use of the MinHeight property in xaml or factor in a MinHeight property in this code.
if (value is int)
{
return ((int)value) * ItemHeight;
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
{
if (value is int)
{
return ((int)value) / ItemHeight;
}
return value;
}
}
您的ListBox需要更改为:
<ListBox ItemsSource="{Binding Items}" Margin="0 0 0 5"
Height="{Binding MaxVisibleItems, Converter={StaticResource FixedHeightConverter}}">
<ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</ListBox.ItemsPanel>
</ListBox>
请注意,如果您想在UI的其他部分重复使用它,并且您有不同的固定高度,那么您可以考虑将ItemHeight设为属性而不是const。
答案 2 :(得分:0)
由于您的商品具有固定的高度,我建议您以这种方式扩展ListBox
控件:
namespace WpfApplication1
{
public class ListBox : System.Windows.Controls.ListBox
{
public ListBox()
{
Loaded += new RoutedEventHandler(OnLoaded);
}
private void OnLoaded(object sender, RoutedEventArgs e)
{
if (MaxVisibleItemsCount < Int32.MaxValue)
{
MaxHeight = (ActualHeight / Items.Count) * MaxVisibleItemsCount;
}
}
public int MaxVisibleItemsCount
{
get { return (int)GetValue(MaxVisibleItemsCountProperty); }
set { SetValue(MaxVisibleItemsCountProperty, value); }
}
public static readonly DependencyProperty MaxVisibleItemsCountProperty =
DependencyProperty.Register("MaxVisibleItemsCount", typeof(int), typeof(ItemsControl), new UIPropertyMetadata(Int32.MaxValue));
}
}
然后你的XAML将是:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="clr-namespace:WpfApplication1"
xmlns:sys="clr-namespace:System;assembly=mscorlib"
Title="Window1" Height="300" Width="300">
<Window.Resources />
<DockPanel>
<local:ListBox Margin="5" DockPanel.Dock="Top"
MaxVisibleItemsCount="5"
VirtualizingStackPanel.VirtualizationMode="Recycling"
VirtualizingStackPanel.IsVirtualizing="True">
<local:ListBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel/>
</ItemsPanelTemplate>
</local:ListBox.ItemsPanel>
<local:ListBox.Items>
<sys:String>One</sys:String>
<sys:String>Two</sys:String>
<sys:String>Three</sys:String>
<sys:String>Four</sys:String>
<sys:String>Five</sys:String>
<sys:String>Six</sys:String>
<sys:String>Seven</sys:String>
<sys:String>Eight</sys:String>
<sys:String>Nine</sys:String>
<sys:String>Ten</sys:String>
</local:ListBox.Items>
</local:ListBox>
<Grid />
</DockPanel>
</Window>
我用Grid
来填补余下的空间。如果没有此Grid
,ListBox将扩展其高度以填充窗口中的可用空间。