WPF:是否有可能多次在ItemsControl上显示一个项目?

WPF:是否有可能多次在ItemsControl上显示一个项目?

问题描述:

我想创建一个控件,但我真的不知道如何用英文来命名它,这就是为什么我不知道该如何谷歌。WPF:是否有可能多次在ItemsControl上显示一个项目?

因此,如果已经有它的名称和/或如果已经有一个具有以下功能的控件,请让我知道。

我的控制是某种ItemsControl,但有一个区别。如果它包含的项目太少而无法完全填充视口,则应该再次从第一个项目开始,直到视口完全填充。所以,如果视口有空间让我们说五个项目,并且我的ItemsSource只包含两个项目,控件应该显示项目1,然后是2,然后是1,然后是2,然后是1再次显示1。回到顶端这篇文章中的信息适用于:????????????????

把它看作是电视新闻频道底部的新闻频道的WPF等价物。它围绕着可用的物品进行盘旋,如果它到达终点,它将再次从第一个物品开始,两者之间没有间隙。

我已经尝试为此创建自己的面板,但我找不到在此面板中多次显示一个项目的方法。这甚至有可能吗?

你将如何创建这样的控制?我可以基于默认ItemsControl或我必须从Control继承,并从头开始?

谢谢你的想法和推动正确的方向。


编辑1:

我尝试了以下遵循建议的答复1.

我创建了一个RecurringEnumerator(Of T)

Imports System.Collections.ObjectModel 

Public Class RecurringEnumerator(Of T) 
    Implements IEnumerator(Of T) 

    Private _internal As ICollection(Of T) 
    Private _currentIndex As Integer 

    Public Sub New(ByVal internal As ICollection(Of T)) 
     If (internal Is Nothing) Then 
      Throw New ArgumentNullException("internal") 
     End If 

     _internal = internal 
     _currentIndex = -1 
    End Sub 

    Public ReadOnly Property Current As T Implements IEnumerator(Of T).Current 
     Get 
      Return _internal(_currentIndex) 
     End Get 
    End Property 

    Public ReadOnly Property CurrentObject As Object Implements IEnumerator.Current 
     Get 
      Return _internal(_currentIndex) 
     End Get 
    End Property 

    Public Function MoveNext() As Boolean Implements IEnumerator.MoveNext 
     If (_internal.Count = 0) Then 
      Return False 
     End If 

     _currentIndex += 1 

     If (_currentIndex >= _internal.Count) Then 
      _currentIndex -= _internal.Count 
     End If 

     Return True 
    End Function 

    Public Sub Reset() Implements IEnumerator.Reset 
     _currentIndex = -1 
    End Sub 

    Public Sub Dispose() Implements IDisposable.Dispose 
    End Sub 

End Class 

然后我在用这个RecurringEnumerator(Of T)RecurringCollection(Of T): 公共类RecurringCollection(Of T) 实施ICollection (OF T)

Private _enumerator As RecurringEnumerator(Of T) 
    Private _internal As ObjectModel.Collection(Of T) 

    Public Sub New() 
     _enumerator = New RecurringEnumerator(Of T)(Me) 
     _internal = New ObjectModel.Collection(Of T) 
    End Sub 

    Public Function GetEnumerator() As IEnumerator(Of T) Implements IEnumerable(Of T).GetEnumerator 
     Return _enumerator 
    End Function 

    Public Function GetObjectEnumerator() As IEnumerator Implements IEnumerable.GetEnumerator 
     Return _enumerator 
    End Function 

    Public Sub Add(ByVal item As T) Implements ICollection(Of T).Add 
     _internal.Add(item) 
    End Sub 

    Public Sub Clear() Implements ICollection(Of T).Clear 
     _internal.Clear() 
    End Sub 

    Public Function Contains(ByVal item As T) As Boolean Implements ICollection(Of T).Contains 
     Return _internal.Contains(item) 
    End Function 

    Public Sub CopyTo(ByVal array() As T, ByVal arrayIndex As Integer) Implements ICollection(Of T).CopyTo 
     _internal.CopyTo(array, arrayIndex) 
    End Sub 

    Public ReadOnly Property Count As Integer Implements ICollection(Of T).Count 
     Get 
      Return _internal.Count 
     End Get 
    End Property 

    Public ReadOnly Property IsReadOnly As Boolean Implements ICollection(Of T).IsReadOnly 
     Get 
      Return False 
     End Get 
    End Property 

    Public Function Remove(ByVal item As T) As Boolean Implements ICollection(Of T).Remove 
     Return _internal.Remove(item) 
    End Function 

End Class 

但是把三个短字符串这个RecurringCollection(Of T)内部和换eaching通过收集和显示每个串的消息框导致了*Exception没有示出至少一个消息框。

我之前没有创建自定义集合,所以我不确定我是否做得正确。

而不是试图操纵ItemsControl你可以创建一个专门的集合。我在下面写了一个模板。为了简洁起见,我省略了错误检查和其他ICollection<T>方法。您可以轻松将这些方法委托给内部列表。

public class RecurringList<T> : ICollection<T> 
{ 
    private readonly List<T> _items = new List<T>(); 

    public int DesiredCount { get; set; } 
    public int Count => _items.Count > 0 ? DesiredCount : 0; 

    public bool IsReadOnly => false; 

    public IEnumerator<T> GetEnumerator() 
    { 
     if (_items.Count == 0) 
     { 
      yield break; 
     } 

     int count = Math.Max(DesiredCount, _items.Count); 

     for (int i = 0; i < count; i++) 
     { 
      yield return _items[i % _items.Count]; 
     } 
    } 

    IEnumerator IEnumerable.GetEnumerator() 
    { 
     return GetEnumerator(); 
    } 

    public void Add(T item) 
    { 
     _items.Add(item); 
    } 

    public void Clear() 
    { 
     _items.Clear(); 
    } 

    public bool Contains(T item) 
    { 
     return _items.Contains(item); 
    } 

    public void CopyTo(T[] array, int arrayIndex) 
    { 
     _items.CopyTo(array, arrayIndex); 
    } 

    public bool Remove(T item) 
    { 
     return _items.Remove(item); 
    } 
} 
+0

@Downvoter Care to comment? –

+0

我不是downvoter! 我试过你的解决方案,但是你的代码没有工作,比如你的函数'GetEnumerator'返回的是Type T的值,但是应该返回'IEnumerator '。 请参阅我的编辑问题,而不是我尝试的。 – Nostromo

+0

我试过这个解决方案,它运行良好。 'GetEnumerator'函数** yield **返回'T'。这是C#的'IEnumerable'模式。你可以看到一个解释[这里](http://james-ramsden.com/implement-ienumerable-c/)。 –