2014-03-01 39 views
2

我想要的就像Linq Distinct,可以顯示重複或不重複,具體取決於複選框的狀態。我有一個WPF列表視圖,根據複選框的值,我想顯示重複的值。

這是XAML(有類似名稱的所有屬性,以及關於版面去除一切,爲了避免分心):

<ScrollViewer> 
    <ListView SelectionMode="Single"/> 
</ScrollViewer> 
<CheckBox Content="group duplicates" Checked="CheckBox_Checked" Unchecked="CheckBox_Unchecked"/> 

我的列表視圖中的每個項目是一個超鏈接的標籤,因爲它的內容,當點擊時,用默認的互聯網瀏覽器打開超鏈接的NavigateUri屬性中設置的Uri。

當應用程序運行時,某些鏈接出現不止一次,這是相關的,因爲它顯示了這些URI的發生次數。在建立列表時,我無法擺脫重複項,因爲它是按每個uri發生的時間排序的,這也是相關的。

因爲難以對人眼,因爲事實上,他們看起來很像很多每個URI之間的區別,這將是實際的,能夠做兩件事情:

  1. 註釋中的鏈接該URI出現在列表視圖的次數,即使它顯示了重複
  2. 的重複摺疊成一個鏈接(與occurencies正確註釋的數量)

我希望達到的效果會是這樣的:

(顯示一式兩份)

  • URI1(2)
  • URI2(3)
  • URI1(2)
  • uri3(1)
  • URI2(3)
  • uri2(3)

(分組複製TES)

  • URI1(2)
  • URI2(3)
  • uri3(1)

這是我的填充listvew在後面的代碼在時刻(不相關的部分不避免分心)

foreach (string uriStr in uriStrCollection) 
{ 
    Uri uri = new Uri(uriStr); 
    Label lbl = new Label(); 
    Hyperlink link = new Hyperlink(); 
    link.Inlines.Add(uriStr); 
    link.NavigateUri = uri; 
    link.RequestNavigate += link_RequestNavigate; 
    lbl.Content = link; 
    listView.Items.Add(lbl); 
} 

存儲uriStrCollection不是一個好的解決方案,因爲它很大,它會基本上存儲相同的數據兩次。

再次生成uriStrCollection是一個更糟糕的想法,因爲該過程涉及更多的內存和計算。

我試着在ListView.Items和ListView.Items上使用Linq擴展方法。SourceCollection,但我不能:Linq方法甚至不顯示自動完成,這對我來說很奇怪,特別是因爲SourceCollection的編譯時類型是IEnumerable。

任何想法?

+0

使用Hashset而不是ListView – Gilad

+0

我希望能夠在窗口上顯示它。就我所知,Hashset不是一個控件。此外,我想保留訂單和重複。我只是想能夠選擇顯示重複或不重複。 – user3251430

+0

確切地說,HashSet不是一個UI控件。使用集合作爲用戶界面的UI控件。可以將這些項目添加到List和HashSet中,或者使用linq來區別List使用GroupBy。 – Paparazzi

回答

1

由於您使用的是WPF,因此我們先從WPF開始 - 從UI分離數據;該UI應該用於顯示的數據,而不是存儲它。

現在忘記用戶界面。首先,創建你需要存儲的URI列表和它們在代碼中出現的類和數據結構,例如:

public class UriWithOccurrence 
{ 
    public string UriString { get; set; } 
    public int Occurrences { get; set; } 
} 

... 

//Keep a global collection of URIs: 
_allUris = new List<UriWithOccurrence>(); 

foreach (string uriStr in uriStrCollection) 
{ 
    var item = new UriWithOccurrence() 
       { 
        UriString = uriStr, 
        Occurrences = uriStrCollection.Count(s => (s == uriStr)) 
       }; 

    _allUris.Add(item); 
} 

現在我們開始考慮在UI顯示這些URI的創建ListView,可以列出UriWithOccurrence s。注意DisplayMemberBinding S的指向特性在UriWithOccurrence:

<ListView x:Name="_list" > 
    <ListView.View> 
     <GridView> 
      <GridViewColumn Header="Link" DisplayMemberBinding="{Binding UriString}" /> 
      <GridViewColumn Header="#" DisplayMemberBinding="{Binding Occurrences}" /> 
     </GridView> 
    </ListView.View> 
</ListView> 

爲連接點,看到一些的URI,我們設置ListView的ItemsSource我們的URI集合:

_list.ItemsSource = _allUris; 

這篇文章解釋了這一切更深度:http://tech.pro/tutorial/742/wpf-tutorial-using-the-listview-part-1

要獲得點擊的URI,這個MSDN問題可能會有所幫助:WPF ListView "hyperlink url" column

最後,獲得了「組重複」複選框的工作,一個快速和骯髒的解決辦法是:

private void CheckBox_Checked(object sender, EventArgs e) 
{ 
    _list.ItemsSource = _allUris; 
} 

private void CheckBox_UnChecked(object sender, EventArgs e) 
{ 
    _list.ItemsSource = _allUris.GroupBy(u => u.UriString) 
           .Select(gr => gr.First()); 
} 

最後提示:

真的做到這一點的WPF方式,請閱讀MVVM模式,並將大部分代碼放在ViewModel中。

+0

謝謝,解決了它。我想簡單地試圖避免WPF的方式。例如,我不願意爲此創建一個新類型,而是單獨列出一個List,希望能夠使用Listview中構建的List。我喜歡簡短的解決方案,但我想這並非總是可行的,有時我們必須在代碼中添加更多內容,不僅要使其運行起來,還要讓其他人更容易理解。再次,謝謝。 – user3251430

+0

是的,它採取不同的思維模式。但是,一旦你的項目增長了一點點,我發現它實際上減少了所需的代碼量,以及在你指出的時候更易於理解。 – Sphinxxx

相關問題