第七色在线视频,2021少妇久久久久久久久久,亚洲欧洲精品成人久久av18,亚洲国产精品特色大片观看完整版,孙宇晨将参加特朗普的晚宴

為了賬號(hào)安全,請(qǐng)及時(shí)綁定郵箱和手機(jī)立即綁定
已解決430363個(gè)問題,去搜搜看,總會(huì)有你想問的

是否可以以編程方式滾動(dòng) WPF ListView,以便將所需的分組標(biāo)題放置在其頂部?

是否可以以編程方式滾動(dòng) WPF ListView,以便將所需的分組標(biāo)題放置在其頂部?

C#
白衣非少年 2023-07-09 15:05:05
給定ListView已使用 a 分組的項(xiàng)目的綁定PropertyGroupDescription,是否可以以編程方式滾動(dòng)以便將組放置在列表的頂部?我知道我可以滾動(dòng)到組中的第一個(gè)項(xiàng)目,因?yàn)樵擁?xiàng)目屬于綁定到的集合ListView。但是,我無法找到任何描述如何滾動(dòng)到組標(biāo)題(樣式為GroupStyle)的資源。為了給出所需功能的示例,讓我們看一下Visual Studio Code中的設(shè)置頁面。該頁面包含一個(gè)面板,允許用戶滾動(dòng)瀏覽所有應(yīng)用程序的設(shè)置(在各自的組下組織)以及左側(cè)的樹結(jié)構(gòu),以便更快地導(dǎo)航到主面板中的特定組。在所附的屏幕截圖中,我單擊左側(cè)樹中的“格式化”選項(xiàng),主面板自動(dòng)滾動(dòng),以便相應(yīng)的組標(biāo)題位于主面板的頂部。如何在 WPF 中重新創(chuàng)建它(如果可能的話)?Visual Studio Code中主設(shè)置面板的“無限”滾動(dòng)是否可以用另一個(gè) WPF 控件來模仿?
查看完整描述

1 回答

?
Cats萌萌

TA貢獻(xiàn)1805條經(jīng)驗(yàn) 獲得超9個(gè)贊

左側(cè)的樹(目錄)具有根節(jié)點(diǎn)(例如“TextEditor”部分)。每個(gè)部分都包含設(shè)置類別(例如“格式”)。右側(cè)ListView(設(shè)置視圖)的項(xiàng)目具有組標(biāo)題,其類別名稱與目錄名稱相匹配(例如,格式)。

1. 編輯以解決使用PropertyGroupDescription

假設(shè):

  • 在 a 內(nèi)部存在一個(gè)CollectionViewSource定義?ResourceDictionary并命名為CollectionViewSource。

  • 設(shè)置數(shù)據(jù)項(xiàng)具有屬性SettingsCategoryName(例如格式)。

  • SettingsCategoryNameSelectedItem綁定?TreeView到一個(gè)屬性SelectedSettingsCategoryName

查看.xaml:

<ResourceDictionary>

? <CollectionViewSource x:Key="CollectionViewSource" Source="{Binding Settings}">

? ? ? <CollectionViewSource.GroupDescriptions>

? ? ? ? <PropertyGroupDescription PropertyName="SettingsCategoryName"/>

? ? ? </CollectionViewSource.GroupDescriptions>

? </CollectionViewSource>

</ResourceDictionary>


<ListView x:Name="ListView" ItemsSource="{Binding Source={StaticResource CollectionViewSource}}">

? <ListView.GroupStyle>

? ? <GroupStyle>

? ? ? <GroupStyle.HeaderTemplate>

? ? ? ? <DataTemplate>

? ? ? ? ? <TextBlock FontWeight="Bold"

? ? ? ? ? ? ? ? ? ? ?FontSize="14"

? ? ? ? ? ? ? ? ? ? ?Text="{Binding Name}" />

? ? ? ? </DataTemplate>

? ? ? </GroupStyle.HeaderTemplate>

? ? </GroupStyle>

? </ListView.GroupStyle>

</ListView>

View.xaml.cs:

找到選定的類別并將其滾動(dòng)到視口的頂部。


// Scroll the selected section to top when the selected item has changed

private void ScrollToSection()

{

? CollectionViewSource viewSource = FindResource("CollectionViewSource") as CollectionViewSource;

? CollectionViewGroup selectedGroupItemData = viewSource

? ? .View

? ? .Groups

? ? .OfType<CollectionViewGroup>()

? ? .FirstOrDefault(group => group.Name.Equals(this.SelectedSettingsCategoryName));


? GroupItem selectedroupItemContainer = this.ListView.ItemContainerGenerator.ContainerFromItem(selectedGroupItemData) as GroupItem;


? ScrollViewer scrollViewer;

? if (!TryFindCildElement(this.ListView, out scrollViewer))

? {

? ? return;

? }


? // Subscribe to scrollChanged event?

? // because the scroll executed by `BringIntoView` is deferred.

? scrollViewer.ScrollChanged += ScrollSelectedGroupToTop;


? selectedGroupItemContainer?.BringIntoView();

}


private void ScrollSelectedGroupToTop(object sender, ScrollChangedEventArgs e)

{

? ScrollViewer scrollViewer;

? if (!TryFindCildElement(this.ListView, out scrollViewer))

? {

? ? return;

? }


? scrollViewer.ScrollChanged -= ScrollGroupToTop;

? var viewSource = FindResource("CollectionViewSource") as CollectionViewSource;


? CollectionViewGroup selectedGroupItemData = viewSource

? ? .View

? ? .Groups

? ? .OfType<CollectionViewGroup>()

? ? .FirstOrDefault(group => group.Name.Equals(this.SelectedSettingsCategoryName));


? var groupIndex = viewSource

? ? .View

? ? .Groups.IndexOf(selectedGroupItemData);


? var absoluteVerticalScrollOffset = viewSource

? ? .View

? ? .Groups

? ? .OfType<CollectionViewGroup>()

? ? .TakeWhile((group, index) => index < groupIndex)

? ? .Sum(group =>

? ? ? (this.ListView.ItemContainerGenerator.ContainerFromItem(group) as GroupItem)?.ActualHeight?

? ? ??? 0

? ? );


? scrollViewer.ScrollToVerticalOffset(absoluteVerticalScrollOffset);

}


// Generic method to find any `DependencyObject` in the visual tree of a parent element

private bool TryFindCildElement<TElement>(DependencyObject parent, out TElement resultElement) where TElement : DependencyObject

{

? resultElement = null;

? for (var childIndex = 0; childIndex < VisualTreeHelper.GetChildrenCount(parent); childIndex++)

? {

? ? DependencyObject childElement = VisualTreeHelper.GetChild(parent, childIndex);


? ? if (childElement is Popup popup)

? ? {

? ? ? childElement = popup.Child;

? ? }


? ? if (childElement is TElement)

? ? {

? ? ? resultElement = childElement as TElement;

? ? ? return true;

? ? }


? ? if (TryFindCildElement(childElement, out resultElement))

? ? {

? ? ? return true;

? ? }

? }


? return false;

}

您可以將此方法移至ListView派生類型中。然后將 a 添加到處理路由命令的CommandBindings新自定義中,例如。將 模板化為 a并讓它們發(fā)出命令以將節(jié)名稱傳遞給自定義.ListViewScrollToSectionRoutedCommandTreeViewItemsButtonCommandParameterListView

備注
由于使用PropertyGroupDescription結(jié)果會(huì)產(chǎn)生混合數(shù)據(jù)類型的項(xiàng)目源(GroupItemData對(duì)于組標(biāo)頭以及實(shí)際數(shù)據(jù)項(xiàng)目),因此托管的 UI 虛擬化ItemsControl已禁用且不可能(。在這種情況下,附加屬性ScrollViewer.CanContentScroll會(huì)自動(dòng)設(shè)置為False(強(qiáng)制)。對(duì)于大列表來說,這可能是一個(gè)巨大的缺點(diǎn),也是采用替代方法的原因。

2.替代解決方案(支持UI虛擬化)

當(dāng)涉及到實(shí)際設(shè)置結(jié)構(gòu)的設(shè)計(jì)時(shí),存在多種可能的變化。它可以是一棵樹,其中每個(gè)類別標(biāo)題節(jié)點(diǎn)都有自己的子節(jié)點(diǎn),這些子節(jié)點(diǎn)表示類別的設(shè)置,也可以是一個(gè)平面列表結(jié)構(gòu),其中類別標(biāo)題和設(shè)置都是同級(jí)的。為了使示例簡單起見,我選擇第二個(gè)選項(xiàng):平面列表數(shù)據(jù)結(jié)構(gòu)。

2.1 設(shè)置

基本思想:使用具有兩個(gè)級(jí)別的
模板進(jìn)行模板化。第二層(葉子)和共享標(biāo)題項(xiàng)的相同實(shí)例(見下文)。因此,選定的標(biāo)題項(xiàng)目引用了完全相同項(xiàng)目標(biāo)題- 無需搜索。TreeViewHierarchicalDataTemplateTreeViewListViewIHeaederDataTreeViewListView

實(shí)施概述:

  • 您需要兩個(gè)ItemsControl元素:

    • 帶有節(jié)根節(jié)點(diǎn)(例如“文本編輯器”)

    • 以及該部分的設(shè)置類別標(biāo)題子節(jié)點(diǎn)(葉節(jié)點(diǎn))(例如“字體”、“格式”)

    • TreeView左側(cè)導(dǎo)航窗格有?兩層

    • 一個(gè)ListView用于實(shí)際設(shè)置及其類別標(biāo)題。

  • 然后設(shè)計(jì)數(shù)據(jù)類型來表示設(shè)置、設(shè)置標(biāo)頭和節(jié)根節(jié)點(diǎn)

    • 讓它們都實(shí)現(xiàn)一個(gè)IData具有共享屬性的共同點(diǎn)(例如標(biāo)頭)

    • 讓設(shè)置頭數(shù)據(jù)類型實(shí)現(xiàn)一個(gè)額外的?IHeaderData

    • 讓設(shè)置數(shù)據(jù)類型實(shí)現(xiàn)一個(gè)額外的ISettingData

    • 讓父節(jié)節(jié)點(diǎn)數(shù)據(jù)類型(根節(jié)點(diǎn))用于實(shí)現(xiàn)具有子節(jié)點(diǎn)類型的TreeView附加節(jié)點(diǎn)ISectionDataIHeaderData

  • 創(chuàng)建項(xiàng)目源集合(所有類型IEnumerable<IData>

    • TreeView一個(gè)用于(僅保存類別)的每個(gè)父節(jié)節(jié)點(diǎn),aSectionCollection類型ISectionData

    • 每個(gè)類別一個(gè),一個(gè)CategoryCollection類型IHeaderData

    • 單個(gè)用于設(shè)置數(shù)據(jù)和共享類別(標(biāo)題數(shù)據(jù)),aSettingCollection類型IData

  • 逐節(jié)填充已排序的源集合

    • 將類型的節(jié)數(shù)據(jù)實(shí)例添加到的ISectionData源集合中SectionCollectionTreeView

    • 將類型的共享類別數(shù)據(jù)頭實(shí)例添加IHeaderData到兩個(gè)源集合中CategoryCollection,并且SettingCollection

    • 將 type 的設(shè)置實(shí)例添加ISettingData到唯一SettingCollection

    • 對(duì)當(dāng)前部分的所有類別重復(fù)最后兩個(gè)步驟

    • 將 分配給根節(jié)點(diǎn)CategoryCollection的子集合ISectionData

    • 對(duì)所有部分重復(fù)這些步驟(及其類別和相應(yīng)的設(shè)置)

  • 將 綁定SectionCollection到?TreeView

  • 將 綁定SettingsCollectionLIstView

  • HierarchicalDataTemplateTreeView數(shù)據(jù)創(chuàng)建一個(gè)ISectionData類型為根的數(shù)據(jù)

  • 創(chuàng)建兩個(gè)DataTemplate用于ListView

    • 一個(gè)目標(biāo)IHeaderData

    • 一個(gè)目標(biāo)ISettingData

邏輯:

  • 當(dāng)選擇?IHeaderData其中的一項(xiàng)時(shí)TreeView

    • ListView使用獲取此數(shù)據(jù)項(xiàng)的項(xiàng)目容器var container = ItemsContainerGenerator.GetContainerFromItem(selectedTreeViewCategoryItem)

    • 將容器滾動(dòng)到視圖中container.BringIntoView()(實(shí)現(xiàn)視圖外的虛擬化項(xiàng)目)

    • 將容器滾動(dòng)到視圖頂部

因?yàn)?code>TreeView和ListView共享相同的類別標(biāo)題數(shù)據(jù) (?IHeaderData),所以所選項(xiàng)目很容易跟蹤和查找。您不必搜索設(shè)置組。您可以使用參考直接跳轉(zhuǎn)到該組。這意味著數(shù)據(jù)的結(jié)構(gòu)是解決方案的關(guān)鍵。



查看完整回答
反對(duì) 回復(fù) 2023-07-09
  • 1 回答
  • 0 關(guān)注
  • 249 瀏覽

添加回答

舉報(bào)

0/150
提交
取消
微信客服

購課補(bǔ)貼
聯(lián)系客服咨詢優(yōu)惠詳情

幫助反饋 APP下載

慕課網(wǎng)APP
您的移動(dòng)學(xué)習(xí)伙伴

公眾號(hào)

掃描二維碼
關(guān)注慕課網(wǎng)微信公眾號(hào)