2017-08-06 91 views
1

我想創建一個控件,但我真的不知道如何用英文來命名它,這就是爲什麼我不知道該如何谷歌。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通過收集和顯示每個串的消息框導致了StackOverflowException沒有示出至少一個消息框。

我之前沒有創建自定義集合,所以我不確定我是否做得正確。

回答

-1

而不是試圖操縱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/)。 –

相關問題