ItemsControl 내의 바운드 컬렉션에서 몇 가지 항목 만 표시하는 방법을 알고 있는지 궁금합니다. ICollectionView 또는 다른 방법을 필터링하여 표시할지 여부. 나는 독자적으로 장황한 해결책을 제시 할 수있을 것이라고 확신하지만 이미 무엇이 있는지보고 싶습니다.ItemsControl 내에서 컬렉션의 몇 가지 항목 만 표시하는 방법 - Silverlight
기본적으로 모델에 포함 된 개체 컬렉션에 바운드 된 ItemsControl이 있습니다. 내가하고 싶은 것은 그 중 몇 가지 항목 만 표시 한 다음 "더보기"를위한 하이퍼 링크/버튼이 있습니다. 어느 항목의 전체 컬렉션을 표시합니다. VSM을 사용하여 '축소 된'상태와 '확장 된 상태'를 알릴 수 있기를 희망했지만 목록을 초기화하는 방법에 대해 머리를 감싸는 데 문제가 있습니다. 바인딩은 XAML에서 만들어 지므로 코드 숨김에서 Linq를 사용하여 ItemsSource 컬렉션을 수동으로 수정하는 것을 피하려고합니다. 이는 다른 모든 것이 실패 할 경우 솔루션이 될 수 있습니다.
필요한 경우 일부 코드를 표시 할 수 있지만 내 설명보다 더 도움이되지 않을 것이라고 생각합니다. 다시 말하지만, 나는 너무 많은 실험을하고 내 뷰 모델을 깨는 것을 끝내기 전에 누군가가 비슷한 것을했기를 바랄뿐입니다.
미리 감사드립니다.
[업데이트] - 이것은 (다른 사람이 똑같은 일을하기를 원한다면) 많은 브레인 스토밍 후에 나왔던 해결책입니다. 아이디어 덕분에 AnthonyWJones에게 감사드립니다.
내가 한 것은 모델의 원본 컬렉션과 '보기'컬렉션 사이의 다리 역할을하는 일반 '모델'을 결합한 것입니다. 의도 된 목적은 동일한 UI (컨트롤 및 템플릿)를 사용하는 동안 주석이있을 수있는 WCF RIA Service에 의해 생성 된 모든 모델 클래스를 확장하여 예상 컬렉션이 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;
}
그리고 지금 우리가 그것을 사용할 필요가 : 엔티티 '다음 클래스의
모든 실버 라이트 클라이언트 프로젝트
먼저 작은 배관에 선언되어있다. 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;
}
}
}
'Timeline'클래스가 데이터/바인딩 컨텍스트 인 바인딩에서 주석 모델을 참조 할 수 있습니다.
예 :
<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 개만 표시되고 사용자가 "모두 표시"또는 "더보기"를 클릭하면 다음 2를 표시하는 대신 10 개를 모두 표시합니다. – SilverX
I 당신이 재사용 할 수있는 것이 아무것도 없다고 생각하지 마십시오. 이것은 당신이 자신을 구현하는 데 필요한 것 같은데. 하지만 어쩌면 누군가가 나를 틀리게 증명할 것입니다. =) – CodingGorilla