我想知道是否有人知道如何僅顯示ItemsControl中的綁定集合中的幾個項目。無論是通過過濾ICollectionView還是其他方式。我確信我可以自己想出一個冗長的解決方案,但我想看看那裏已經有了什麼。如何在ItemsControl中只顯示一個集合的幾個項目 - Silverlight
基本上,我有一個ItemsControl綁定到模型中包含的對象的集合。我想要做的只是顯示其中一些項目,然後有一個「查看更多」的超鏈接/按鈕。這將顯示整個項目的集合。我一直希望能夠使用VSM發出'摺疊'和'擴展'狀態的信號,但是我在如何初始化列表時遇到了問題。由於綁定是在XAML中創建的,因此我試圖避免在代碼隱藏中使用Linq手動修改ItemsSource集合,如果其他所有集合都失敗,這可能是一個解決方案。
如果需要,我可以顯示一些代碼,但我認爲這不會比我的解釋更有幫助。再次,我只是希望有人在那裏做了類似的事情,然後我嘗試了太多,最終打破了我的viewmodel哈哈。
在此先感謝。
[更新] - 這是我經過頭腦風暴(對於其他人希望做同樣的事情)後想出的解決方案。感謝AnthonyWJones的想法。
我所做的是將一個通用「模型」放在一起,充當模型的源集合和「視圖」集合之間的橋樑。預期目的(對我而言)是擴展由WCF RIA服務生成的任何模型類,在使用相同的UI(控件和模板)時可能有與其相關的註釋,因此期望的集合是一個EntityCollection,其中T是「
// this is so we can reference our model without generic arguments
public interface ICommentModel : INotifyPropertyChanged
{
Int32 TotalComments { get; }
Int32 VisibleComments { get; }
Boolean IsExpanded { get; set; }
Boolean IsExpandable { get; }
ICommand ExpandCommand { get; }
IEnumerable Collection { get; }
}
// the command we'll use to expand our collection
public class ExpandCommand : ICommand
{
ICommentModel model;
public ExpandCommand(ICommentModel model) {
this.model = model;
this.model.PropertyChanged += ModelPropertyChanged;
}
public bool CanExecute(object parameter) {
return this.model.IsExpandable;
}
public void Execute(object parameter) {
this.model.IsExpanded = !this.model.IsExpanded;
}
private void ModelPropertyChanged(object sender, PropertyChangedEventArgs e) {
if (e.PropertyName == "IsExpandable")
RaiseCanExecuteChanged();
}
private void RaiseCanExecuteChanged() {
var execute = CanExecuteChanged;
if (execute != null) execute(this, EventArgs.Empty);
}
public event EventHandler CanExecuteChanged;
}
// and finally.. the big guns
public class CommentModel<TEntity> : ICommentModel
where TEntity : Entity
{
Boolean isExpanded;
ICommand expandCommand;
IEnumerable<TEntity> source;
IEnumerable<TEntity> originalSource;
public Int32 TotalComments { get { return originalSource.Count(); } }
public Int32 VisibleComments { get { return source.Count(); } }
public Boolean IsExpanded {
get { return isExpanded; }
set { isExpanded = value; OnIsExpandedChanged(); }
}
public Boolean IsExpandable {
get { return (!IsExpanded && originalSource.Count() > 2); }
}
public ICommand ExpandCommand {
get { return expandCommand; }
}
public IEnumerable Collection { get { return source; } }
public CommentModel(EntityCollection<TEntity> source) {
expandCommand = new ExpandCommand(this);
source.EntityAdded += OriginalSourceChanged;
source.EntityRemoved += OriginalSourceChanged;
originalSource = source;
UpdateBoundCollection();
}
private void OnIsExpandedChanged() {
OnPropertyChanged("IsExpanded");
UpdateBoundCollection();
}
private void OriginalSourceChanged(object sender, EntityCollectionChangedEventArgs<TEntity> e) {
OnPropertyChanged("TotalComments");
UpdateBoundCollection();
}
private void UpdateBoundCollection() {
if (IsExpanded)
source = originalSource.OrderBy(s => PropertySorter(s));
else
source = originalSource.OrderByDescending(s => PropertySorter(s)).Take(2).OrderBy(s => PropertySorter(s));
OnPropertyChanged("IsExpandable");
OnPropertyChanged("VisibleComments");
OnPropertyChanged("Collection");
}
// I wasn't sure how to get instances Func<T,TRet> into this class
// without some dirty hacking, so I used some reflection to run "OrderBy" queries
// All entities in my DataModel have 'bigint' Id columns
private long PropertySorter(TEntity s) {
var props = from x in s.GetType().GetProperties()
where x.Name == "Id"
select x;
if (props.Count() > 0)
return (long)props.First().GetValue(s, null);
return 0;
}
protected virtual void OnPropertyChanged(string propName) {
var x = PropertyChanged;
if (x != null) x(this, new PropertyChangedEventArgs(propName));
}
public event PropertyChangedEventHandler PropertyChanged;
}
現在,我們需要使用它:實體」
以下類的所有在Silverlight客戶端項目
首先一點水暖聲明。 WCF RIA Services會生成標記爲「部分」的類(我不知道是否有情況,但從我看到的情況來看)。所以我們將擴展它生成的實體類以包含我們的新模型。
// this must be inside the same namespace the classes are generated in
// generally this is <ProjectName>.Web
public partial class Timeline
{
ICommentModel model;
public ICommentModel CommentModel {
get {
if (model == null)
model = new CommentModel<TimelineComment>(Comments);
return model;
}
}
}
現在我們可以在'時間軸'類是數據/綁定上下文的綁定中引用評論模型。
例子:
<UserControl x:Class="Testing.Comments"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="291" d:DesignWidth="382">
<Border CornerRadius="2" BorderBrush="{StaticResource LineBrush}" BorderThickness="1">
<Grid x:Name="LayoutRoot">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition/>
</Grid.RowDefinitions>
<StackPanel Visibility="{Binding Path=CommentModel.IsExpandable, Converter={StaticResource BooleanToVisibility}}">
<HyperlinkButton
FontSize="10"
Command="{Binding Path=CommentModel.ExpandCommand}"
Background="{StaticResource BackBrush}">
<TextBlock>
<Run Text="View all"/>
<Run Text="{Binding Path=CommentModel.TotalComments}"/>
<Run Text="comments"/>
</TextBlock>
</HyperlinkButton>
<Rectangle Height="1" Margin="0,1,0,0" Fill="{StaticResource LineBrush}" VerticalAlignment="Bottom"/>
</StackPanel>
<ItemsControl
Grid.Row="1"
ItemsSource="{Binding Path=CommentModel.Collection}"
ItemTemplate="{StaticResource CommentTemplate}" />
</Grid>
</Border>
</UserControl>
所以基本上你想分頁的結果? – CodingGorilla
不是真的在術語的定義。假設集合中有10個項目,並且最初加載時只顯示前2個,如果用戶點擊「全部顯示」或「查看更多」,則顯示全部10個而不顯示下一個2 – SilverX
I不要以爲有什麼可以重複使用的東西;這聽起來像是你需要實現自己的東西。但也許有人會證明我錯了。 =) – CodingGorilla