【发布时间】:2011-01-10 02:47:03
【问题描述】:
有没有办法限制项目控件中显示的行数。 ?
我有一个绑定到 Items 控件的可观察字符串集合。我想将显示的行数限制为一个。集合可以有多个。
谢谢,
【问题讨论】:
-
您如何确定要展示的集合中的哪一项?用户如何更改所选项目?请更改您的问题以添加更多信息,不要为此回答您自己的问题。
标签: wpf binding wpf-controls itemscontrol
有没有办法限制项目控件中显示的行数。 ?
我有一个绑定到 Items 控件的可观察字符串集合。我想将显示的行数限制为一个。集合可以有多个。
谢谢,
【问题讨论】:
标签: wpf binding wpf-controls itemscontrol
您可以为此使用IValueConverter:
public class ItemsLimiter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, string language)
{
int count;
if (Int32.TryParse((string)parameter, out count))
{
return ((IEnumerable<object>)value).Take(count);
}
return value;
}
public object ConvertBack(object value, Type targetType, object parameter, string language)
{
return null;
}
}
在 XAML 中你可以这样使用它:
<ItemsControl ItemsSource="{x:Bind Data, Converter={StaticResource ItemsLimiter}, ConverterParameter=12}">
【讨论】:
假设您的ItemsSource 设置为MyObservableCollection。
好吧,如果你改变你的ItemsSource,让它指向MyOneItemCollection呢?
然后,只需使用 LINQ 执行以下操作:
using System.Linq;
MyOneItemCollection = MyObservableCollection.First();
或
using System.Linq;
MyOneItemCollection = MyObservableCollection.Single(item => item.Id = MyId);
【讨论】:
如果您只需要显示一个项目,您可以使用 ContentControl 显示第一个项目,而不是使用相同的可用模板选项:
<ContentControl DataContext="{erm:Items FieldName}" Content="{Binding [0]}">
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="Wrap" FontSize="14" VerticalAlignment="Center" FontWeight="Bold" />
</DataTemplate>
</ContentControl>
【讨论】:
在这里查看我的 PaginatedObservableCollection http://jobijoy.blogspot.com/2008/12/paginated-observablecollection.html
这是一个 observableCollection 的子类,它允许您绑定到 N 个项目,并在您设置 ItemsPerPage 时使 UI 显示“n”个项目。在你的情况下,如果你放 1 并且可以将下一个和上一个也绑定到我的示例中的某些按钮。
希望这能给你一些想法。
【讨论】:
您可以实现仅提供n 元素的自定义CollectionView。我在我的自动完成文本框控件实现中做了类似的事情,在这里查看:
A Reusable WPF Autocomplete TextBox
向下滚动到标题为 Limiting the Completions List 的标题,看看我在那里做了什么。
【讨论】:
您可以通过创建一个只生成一个项目的CollectionView 来做到这一点。这很简单:只需继承 CollectionView 并覆盖 OnCollectionChanged 以设置过滤器以过滤除基础集合中的第一项之外的所有内容:
protected override void OnCollectionChanged(NotifyCollectionChangedEventArgs args)
{
base.OnCollectionChanged(args);
var first = SourceCollection.FirstOrDefault();
Filter = (obj) => obj == first;
}
现在您需要将此CollectionView 插入您的ItemsSource。如果erm:Items 的ProvideValue 生成实际集合或没有转换器的绑定,您可以创建自己的MarkupExtension,将其包装在您的自定义视图中或添加一个转换器来进行包装。另一方面,如果 erm:Items 生成的 Binding 已经有一个 Converter 或者您不能依赖知道它生成了什么,您可能应该使用更通用的解决方案 - 我建议附加属性。
要使用附加属性,您的 ItemsControl 将像这样绑定:
<ItemsControl
my:SinglerCollectionViewCreator.ItemsSource="{erm:Items FieldName}"
... />
SinglerCollectionViewCreator 类中的代码是:
public class SinglerCollectionViewCreator : DependencyObject
{
public object GetItemsSource(... // use "propa" snippet to fill this in
public void SetItemsSource(....
public static readonly DependencyProperty ItemsSourceProperty = ...
{
PropertyChangedCallback = (obj, e)
{
obj.SetValue(ItemsControl.ItemsSourceProperty,
new SinglerCollectionView(e.NewValue));
}
}
}
这项工作的方式是,每当您在任何对象上设置新的 SinglerCollectionViewCreator.ItemsSource 属性时,该值都将包装在您的 SinglerCollectionView 类中,并且 ItemsControl.ItemsSource 设置在同一对象上。
【讨论】:
有没有办法完全在 XAML 中做到这一点,而无需编写代码?
<ItemsControl Height="100" ItemsSource="{erm:Items FieldName}" Grid.Row="1" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding}" TextWrapping="Wrap" FontSize="14" VerticalAlignment="Center" FontWeight="Bold" />
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
我有像上面那样绑定的项目源。 Items 标记扩展返回可观察的字符串集合,我无法控制可观察的集合。
【讨论】: