WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox
我需要一個(gè)ListBox,他在界面上分為幾列,每列對(duì)應(yīng)一系列的數(shù)據(jù)。第一行是各數(shù)據(jù)的標(biāo)題,支持橫向滾動(dòng),豎向只支持?jǐn)?shù)據(jù)源滾動(dòng),標(biāo)題不隨之滾動(dòng)。視覺上與ListView類似。支持等比拉伸,支持多選,支持從界面去更改內(nèi)部數(shù)據(jù)源,支持子項(xiàng)從ListBox中刪除自己。為了實(shí)現(xiàn)這些功能,我決定自定義一個(gè)特殊的列表,當(dāng)然他還是繼承自ListBox。
1.首先他支持等比拉伸,且數(shù)據(jù)分列顯示。首先想到Grid的ColumnDefinitions可以滿足。
<Grid.ColumnDefinitions> <ColumnDefinition Width="74*" /> <ColumnDefinition Width="179*" /> <ColumnDefinition Width="157*" /> </Grid.ColumnDefinitions>
2.支持從界面去更改內(nèi)部數(shù)據(jù)源,支持子項(xiàng)從ListBox中刪除自己。
為了從界面上滿足功能,需要重寫ItemContainerStyle樣式,繪制出該子項(xiàng)Style。在Style中為了處理事件響應(yīng),可以通過在數(shù)據(jù)源子項(xiàng)中增加Command來對(duì)對(duì)應(yīng)事件進(jìn)行處理。但是處理邏輯可能有點(diǎn)繁雜,而且單從數(shù)據(jù)處理而言,子項(xiàng)無法從父項(xiàng)中刪除自己,只能通過視覺樹獲取父ListBox,實(shí)現(xiàn)該功能。這樣寫的話代碼耦合性會(huì)有點(diǎn)高,且數(shù)據(jù)處理時(shí)會(huì)調(diào)取界面處理。我希望數(shù)據(jù)源內(nèi)部只是在處理數(shù)據(jù),只能通過界面自上而下的訪問數(shù)據(jù)源,而不是數(shù)據(jù)源和界面都有循環(huán)調(diào)用。
第二種方法,我直接重寫一個(gè)控件繼承自ListBoxItem,將之前重寫ItemContainerStyle樣式復(fù)制到該控件前臺(tái),并在后臺(tái)代碼中對(duì)相應(yīng)事件進(jìn)行處理。代碼如下:
public partial class TestItem : ListBoxItem { public TestItem() { InitializeComponent(); } private void Delete_Click(object sender, RoutedEventArgs e) { } }
因?yàn)槲沂抢^承自ListBoxItem的,所以可以通過
ItemsControl.ItemsControlFromItemContainer(this) is ListBox listBox
獲取到父listbox的對(duì)象,獲取到父對(duì)象后,就可以從ListBox中刪除自己?;蚴歉腖istBox中綁定的數(shù)據(jù)源。
3.我們還需要把這個(gè)自定義的ListBoxItem放到我們自定義的ListBox中,讓所有子項(xiàng)都應(yīng)用這個(gè)自定義的ListboxItem,而不是默認(rèn)的ListboxItem。代碼如下:
internal class TestListBox : ListBox { protected override DependencyObject GetContainerForItemOverride() { return new TestItem(); } }
4.為了實(shí)現(xiàn)數(shù)據(jù)與標(biāo)題分離的滾動(dòng)效果,我單獨(dú)將標(biāo)題拿到外部,對(duì)標(biāo)題進(jìn)行單獨(dú)顯示,Listbox只顯示數(shù)據(jù)。外部滑動(dòng)條支持整體橫向滑動(dòng),Listbox內(nèi)部滑動(dòng)條支持內(nèi)部豎向滑動(dòng)。給兩個(gè)滑動(dòng)條都加上最小寬度。
<ScrollViewer Grid.Row="1" Margin="0,20,0,0" HorizontalScrollBarVisibility="Auto" VerticalScrollBarVisibility="Disabled"> <Border MinWidth="{Binding MinWidth, ElementName=listbox}" BorderBrush="#DFDFDF" BorderThickness="1"> <Grid> <Grid.RowDefinitions> <RowDefinition Height="52" /> <RowDefinition /> </Grid.RowDefinitions> <Grid.ColumnDefinitions> <ColumnDefinition Width="79*" /> <ColumnDefinition Width="104*" /> <ColumnDefinition Width="80*" /> </Grid.ColumnDefinitions> <Border Grid.ColumnSpan="20" Background="#F2F2F2" /> <TextBlock Text="ID" /> <TextBlock Grid.Column="1" Text="編號(hào)" /> <TextBlock Grid.Column="2" Text="操作" /> <controls:TestListBox x:Name="listbox" Grid.Row="1" Grid.ColumnSpan="3" MinWidth="1100" ItemsSource="{Binding ItemsSourceData}" Style="{StaticResource BaseListBoxStyle.WithOutHorizontalScrollViewer}" /> </Grid> </Border> </ScrollViewer>
在Listbox的樣式中取消了橫向滑動(dòng)條的顯示。
<Style x:Key="BaseListBoxStyle.WithOutScrollViewer" TargetType="ListBox"> <Setter Property="BorderThickness" Value="0" /> <Setter Property="Background" Value="Transparent" /> <Setter Property="FocusVisualStyle" Value="{x:Null}" /> <Setter Property="ScrollViewer.CanContentScroll" Value="False" /> <Setter Property="ScrollViewer.PanningMode" Value="Both" /> <Setter Property="Stylus.IsFlicksEnabled" Value="False" /> <Setter Property="VerticalContentAlignment" Value="Center" /> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="ListBox"> <Border x:Name="Bd" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" SnapsToDevicePixels="true"> <ScrollViewer Focusable="false" HorizontalScrollBarVisibility="Disabled" VerticalScrollBarVisibility="Auto"> <ItemsPresenter Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" /> </ScrollViewer> </Border> </ControlTemplate> </Setter.Value> </Setter> </Style>
到此這篇關(guān)于WPF實(shí)現(xiàn)自定義一個(gè)自刪除的多功能ListBox的文章就介紹到這了,更多相關(guān)WPF自刪除多功能ListBox內(nèi)容請(qǐng)搜索腳本之家以前的文章或繼續(xù)瀏覽下面的相關(guān)文章希望大家以后多多支持腳本之家!
相關(guān)文章
SpringBoot讀取yml文件中配置數(shù)組的2種方法
這篇文章主要介紹了SpringBoot讀取yml文件中配置數(shù)組的2種方法,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。如有錯(cuò)誤或未考慮完全的地方,望不吝賜教2021-12-12MybatisPlus,無XML分分鐘實(shí)現(xiàn)CRUD操作
這篇文章主要介紹了MybatisPlus,無XML分分鐘實(shí)現(xiàn)CRUD操作,具有很好的參考價(jià)值,希望對(duì)大家有所幫助。一起跟隨小編過來看看吧2020-08-08Java String源碼分析并介紹Sting 為什么不可變
這篇文章主要介紹了Java String源碼分析并介紹Sting 為什么不可變的相關(guān)資料,需要的朋友可以參考下2017-02-02Spring?Security權(quán)限管理小結(jié)
SpringSecurity是一個(gè)權(quán)限管理框架,核心是認(rèn)證和授權(quán),前面已經(jīng)系統(tǒng)的給大家介紹過了認(rèn)證的實(shí)現(xiàn)和源碼分析,本文重點(diǎn)來介紹下權(quán)限管理,需要的朋友可以參考下2022-08-08使用java + selenium + OpenCV破解騰訊防水墻滑動(dòng)驗(yàn)證碼功能
這篇文章主要介紹了使用java + selenium + OpenCV破解騰訊防水墻滑動(dòng)驗(yàn)證碼,本文通過實(shí)例代碼給大家介紹的非常詳細(xì),對(duì)大家的學(xué)習(xí)或工作具有一定的參考借鑒價(jià)值,需要的朋友可以參考下2020-11-11Java中l(wèi)ist.contains()的用法及拓展
List集合相信大家在開發(fā)過程中幾乎都會(huì)用到,有時(shí)候難免會(huì)遇到集合里的數(shù)據(jù)是重復(fù)的,需要進(jìn)行去除,下面這篇文章主要給大家介紹了關(guān)于Java中l(wèi)ist.contains()的用法及拓展的相關(guān)資料,需要的朋友可以參考下2023-03-03