我們在WPF應(yīng)用端的界面中,使用lepoco/wpfui 來做主要的入口框架,這個項目它的菜單內(nèi)置了不少圖標(biāo),我們需要在動態(tài)菜單的配置中,使用它作為圖標(biāo)的展示處理,本篇隨筆介紹如何基于圖標(biāo)枚舉集合進(jìn)行圖標(biāo)的展示和選擇處理。并擴(kuò)展到Font-Awesome-WPF的處理進(jìn)行展示和選擇。
1、lepoco/wpfui 項目的圖標(biāo)庫
lepoco/wpfui 項目的圖標(biāo)庫來源于Fluent System Icons,項目地址是:https://github.com/microsoft/fluentui-system-icons
這些圖標(biāo)映射到枚舉對象?SymbolRegular 和 SymbolFilled,一個是常規(guī)的,一個是填充的圖標(biāo),如下枚舉對象所示。
?圖標(biāo)主要通過前面的名稱來區(qū)分展示的,圖標(biāo)列表主要展示效果如下所示。
我們可以通過代碼把這些枚舉內(nèi)容全部加載到列表中進(jìn)行使用。
var iconList = EnumHelper.GetMemberKeyValue<SymbolRegular>(); foreach (var icon in iconList) { this.AllItems.Add(new CListItem(icon.Key, icon.Value.ToString())); }
我們?yōu)榱颂幚磉@些圖標(biāo)內(nèi)容,需要按照MVVM的設(shè)計模式,設(shè)計相關(guān)的視圖模型和視圖界面,由于圖標(biāo)比較多,測試一次性展示的時候太過耗時,因此把它們分頁處理,實際運(yùn)行的界面效果如下所示。
1)圖標(biāo)列表選擇界面
?2)圖標(biāo)選擇后的展示界面
我們一般在動態(tài)菜單設(shè)置頁面中用到圖標(biāo)的選擇處理,如下界面所示。
?為了有效的對圖標(biāo)進(jìn)行分頁展示,視圖模型需要包含一些分頁所需的對象信息,如下代碼所示。
/// <summary> /// SymbolRegular 的圖標(biāo)查詢視圖模型 /// </summary> public partial class SymbolRegularListViewModel : BaseViewModel { /// <summary> /// 選擇的圖表項目 /// </summary> [ObservableProperty] private CListItem selectedItem = new(); /// <summary> /// 符合條件的圖標(biāo)列表 /// </summary> [ObservableProperty] private List<CListItem> iconItems = new(); /// <summary> /// 所有圖標(biāo) /// </summary> [ObservableProperty] private List<CListItem> allItems = new(); /// <summary> /// 分頁對象 /// </summary> [ObservableProperty] private PagingData pagerInfo = new PagingData() { CurrentPageIndex = 1, PageSize =60 };
由于圖標(biāo)不用訪問數(shù)據(jù)庫,因此在枚舉讀取初始化后存儲所有的圖標(biāo)集合,并以集合為基礎(chǔ)進(jìn)行圖標(biāo)名稱的檢索及排序處理。
在查詢處理的時候,我們需要把分頁的頁碼和頁面大小等信息轉(zhuǎn)換為記錄數(shù)的跳轉(zhuǎn)及獲取變量,如下所示。
/// <summary> /// 轉(zhuǎn)換下分頁信息,為查詢對象的屬性 /// </summary> protected virtual void ConvertPagingInfo() { //根據(jù)傳入的分頁信息構(gòu)建查詢記錄數(shù)和位置 this.SkipCount = (this.PagerInfo.CurrentPageIndex - 1) * this.PagerInfo.PageSize; this.MaxResultCount = this.PagerInfo.PageSize; }
查詢處理的代碼如下所示(在視圖模型上處理代碼)
/// <summary> /// 觸發(fā)查詢處理命令 /// </summary> /// <returns></returns> [RelayCommand] public virtual void Search() { //切換第一頁 this.PagerInfo.CurrentPageIndex = 1; //查詢更新 GetData(); } /// <summary> /// 根據(jù)分頁和查詢條件查詢,請求數(shù)據(jù) /// </summary> /// <returns></returns> public virtual void GetData() { //轉(zhuǎn)換下分頁信息 ConvertPagingInfo(); if (this.Filter.IsNullOrEmpty()) { this.IconItems = AllItems.Skip(this.SkipCount).Take(this.MaxResultCount).ToList(); this.PagerInfo.RecordCount = this.AllItems.Count; } else { this.IconItems = AllItems.Where(s => s.Text.Contains(this.Filter, StringComparison.OrdinalIgnoreCase)).Skip(this.SkipCount).Take(this.MaxResultCount).ToList(); this.PagerInfo.RecordCount = AllItems.Where(s => s.Text.Contains(this.Filter, StringComparison.OrdinalIgnoreCase)).Count(); } }
選擇圖標(biāo)的列表展示界面,遵循MVVM的視圖界面代碼規(guī)范,標(biāo)準(zhǔn)化處理即可,對查詢搜索框的處理響應(yīng)進(jìn)行查詢處理。
/// <summary> /// SymbolRegularSelectPage.xaml 交互邏輯 /// </summary> public partial class SymbolRegularSelectPage : INavigableView<SymbolRegularListViewModel> { /// <summary> /// 視圖模型對象 /// </summary> public SymbolRegularListViewModel ViewModel { get; } /// <summary> /// 構(gòu)造函數(shù) /// </summary> /// <param name="viewModel">視圖模型對象</param> public SymbolRegularSelectPage(SymbolRegularListViewModel viewModel) { ViewModel = viewModel; DataContext = this; InitializeComponent(); } /// <summary> /// 過濾查詢事件 /// </summary> private void SearchBar_OnSearchStarted(object sender, HandyControl.Data.FunctionEventArgs<string> e) { this.ViewModel.Search(); }
2、對圖標(biāo)使用ItemsControl控件進(jìn)行控制輸出
圖標(biāo)是一個集合對象,因此我們?nèi)绻枰凑瘴覀兏袷竭M(jìn)行展示,可以使用ItemsControl來進(jìn)行處理。
ItemsControl可以通過控制 ItemsControl.ItemsPanel 的ItemsPanelTemplate模板進(jìn)行控制布局面板,可以通過控制 ItemsControl.Template 的ControlTemplate來控制輸出格式的總模板,可以通過控制?ItemsControl.ItemTemplate的DataTemplate來控制輸出每個項目的模板,這個控件ItemsControl提供了很靈活的控制模板處理。如下XAML界面代碼所示。
<ItemsControl x:Name="chkIcons" Height="580" HorizontalContentAlignment="Left" ItemsSource="{Binding ViewModel.IconItems}" ScrollViewer.CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="true" VirtualizingStackPanel.VirtualizationMode="Standard"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid HorizontalAlignment="Left" VerticalAlignment="Top" Columns="10" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Button Width="80" Height="80" Margin="8,8" Padding="0" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="Button_Click" FontSize="32" MouseDoubleClick="Button_MouseDoubleClick" Tag="{Binding}" ToolTip="{Binding Text, Mode=OneTime}" ToolTipService.InitialShowDelay="240"> <ui:SymbolIcon FontSize="48" Foreground="CornflowerBlue" Symbol="{Binding Text}" Tag="{Binding}" ToolTip="{Binding Text}" /> </Button> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.Template> <ControlTemplate TargetType="ItemsControl"> <ScrollViewer Width="Auto" CanContentScroll="True" VerticalScrollBarVisibility="Visible"> <ItemsPresenter /> </ScrollViewer> </ControlTemplate> </ItemsControl.Template> </ItemsControl>
展示界面效果如下所示
當(dāng)然這里面還有分頁的界面代碼,使用的是HandyControl的分頁控件處理。
<hc:Pagination DataCountPerPage="{Binding ViewModel.PagerInfo.PageSize}" IsJumpEnabled="True" MaxPageCount="{Binding ViewModel.PagerInfo.MaxPageCount}" MaxPageInterval="5" PageIndex="{Binding ViewModel.PagerInfo.CurrentPageIndex, UpdateSourceTrigger=PropertyChanged}"> <hc:Interaction.Triggers> <hc:EventTrigger EventName="PageUpdated"> <hc:EventToCommand Command="{Binding ViewModel.PageUpdatedCommand}" PassEventArgsToCommand="True" /> </hc:EventTrigger> </hc:Interaction.Triggers> </hc:Pagination>
而對每項的選擇,我們單擊選中,雙擊選中并返回處理,代碼邏輯如下所示。
private void Button_Click(object sender, RoutedEventArgs e) { var button = (Button)sender; if (button != null) { if (button.Tag is CListItem item) { this.ViewModel.SelectedItem = item; } } } private void Button_MouseDoubleClick(object sender, System.Windows.Input.MouseButtonEventArgs e) { var button = (Button)sender; if (button != null) { if (button.Tag is CListItem item) { this.ViewModel.SelectedItem = item; this.DialogResult = true; } } }
而選擇的信息展示,我們可以通過一個面板來組合展示相關(guān)圖標(biāo)名稱和圖標(biāo)效果即可。
<WrapPanel Grid.Column="0" Margin="10,0" VerticalAlignment="Center" Orientation="Horizontal"> <TextBlock HorizontalAlignment="Left" VerticalAlignment="Center" Text="當(dāng)前選擇:" /> <ui:SymbolIcon FontSize="32" Foreground="CornflowerBlue" Symbol="{Binding ViewModel.SelectedItem.Text}" ToolTip="{Binding ViewModel.SelectedItem.Text}" /> <TextBlock Margin="10,0" HorizontalAlignment="Left" VerticalAlignment="Center" Foreground="Blue" Text="{Binding ViewModel.SelectedItem.Text}" /> </WrapPanel>
確認(rèn)選擇后返回的內(nèi)容展示,我們也是使用類似的方式處理界面的
紅色框的界面XAML代碼如下所示。
<!-- 組合多個控件顯示 --> <hc:ElementGroup Width="350" Height="32" Margin="5" Layout="Stack" Orientation="Horizontal"> <TextBox x:Name="txtIcon" Width="230" hc:TitleElement.Title="圖標(biāo)" hc:TitleElement.TitlePlacement="Left" IsReadOnly="True" Text="{Binding ViewModel.Item.Icon, UpdateSourceTrigger=PropertyChanged}" /> <Border Padding="1,0" Style="{StaticResource BorderRegion}"> <ui:SymbolIcon Width="50" FontSize="32" Symbol="{Binding ViewModel.Item.Icon, UpdateSourceTrigger=PropertyChanged}" /> </Border> <Button Command="{Binding SelectIconCommand}" Content="選擇圖標(biāo)" Style="{StaticResource ButtonPrimary}" /> </hc:ElementGroup>
后面就是存儲處理,按照窗口界面彈出,并存儲對象屬性即可。
3、擴(kuò)展到Font-Awesome-WPF的處理進(jìn)行展示和選擇
在WPF中使用Font-Awesome-WPF 圖標(biāo)組件的很多,它的項目地址:https://github.com/charri/Font-Awesome-WPF/blob/master/README-WPF.md。
我們也可以用類似的方式來整合這個圖標(biāo)組件到項目中進(jìn)行使用。
首先在項目的Nugget上添加安裝FontAwesome.WPF組件。
?或者通過命令進(jìn)行安裝
PM> Install-Package FontAwesome.WPF
在使用的XAML中添加對應(yīng)的命名空間。
xmlns:fa="http://schemas.fontawesome.io/icons/"
這個圖標(biāo)的組件使用比較簡單如下代碼所示。
<fa:FontAwesome Icon="Flag" />
和前面的圖標(biāo)組件處理類似,同樣需要處理圖標(biāo)枚舉到具體圖標(biāo)列表展示的處理過程,圖標(biāo)選擇界面運(yùn)行效果如下所示,由于圖標(biāo)不是很多,所以一次性加載了。
?我們先創(chuàng)建MVVM的視圖模型對象,如下所示代碼。
/// <summary> /// FontAwesome.WPF的圖標(biāo)查詢視圖模型 /// </summary> public partial class FontAwesomeListViewModel : BaseViewModel { [ObservableProperty] private CListItem selectedItem = new(); /// <summary> /// 符合條件的圖標(biāo)列表 /// </summary> [ObservableProperty] private List<CListItem> iconItems = new(); /// <summary> /// 所有圖標(biāo) /// </summary> [ObservableProperty] private List<CListItem> allItems = new(); /// <summary> /// 構(gòu)造函數(shù) /// </summary> public FontAwesomeListViewModel() { this.Title = "FontAwesome.WPF的圖標(biāo)"; //FontAwesomeIcon.Book = 0xf02d var iconList = EnumHelper.GetMemberKeyValue<FontAwesomeIcon>(); foreach (var icon in iconList) { this.AllItems.Add(new CListItem(icon.Key, icon.Value.ToString())); } ResetData(); }
ItemsControl的對象展示類似,如下所示。
<ItemsControl x:Name="chkIcons" Height="900" HorizontalContentAlignment="Left" ItemsSource="{Binding ViewModel.IconItems}" ScrollViewer.CanContentScroll="True" VirtualizingStackPanel.IsVirtualizing="true" VirtualizingStackPanel.VirtualizationMode="Standard"> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <UniformGrid HorizontalAlignment="Left" VerticalAlignment="Top" Columns="9" /> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Button Width="80" Height="80" Margin="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" Click="Button_Click" FontSize="32" MouseDoubleClick="Button_MouseDoubleClick" Tag="{Binding}" ToolTip="{Binding Text, Mode=OneTime}" ToolTipService.InitialShowDelay="240"> <fa:ImageAwesome Width="32" HorizontalAlignment="Center" VerticalAlignment="Center" Foreground="CornflowerBlue" Icon="{Binding Text}" Tag="{Binding}" /> </Button> </DataTemplate> </ItemsControl.ItemTemplate> <ItemsControl.Template> <ControlTemplate TargetType="ItemsControl"> <ScrollViewer Width="Auto" CanContentScroll="True" VerticalScrollBarVisibility="Visible"> <ItemsPresenter /> </ScrollViewer> </ControlTemplate> </ItemsControl.Template> </ItemsControl>
其實處理的邏輯類似了。在調(diào)用的父頁面中展示也是使用相應(yīng)的圖標(biāo)代碼即可。
<fa:FontAwesome Width="50" FontSize="32" Icon="{Binding ViewModel.Item.Icon, UpdateSourceTrigger=PropertyChanged}" ToolTip="{Binding ViewModel.Item.Icon}" />
這樣通過動態(tài)配置的菜單,我們就可以讓它在系統(tǒng)運(yùn)行的時候動態(tài)加載對應(yīng)的菜單圖標(biāo)了。
菜單模塊配置界面列表效果。
系統(tǒng)運(yùn)行,動態(tài)從后端獲取菜單及圖標(biāo)展示如下所示。
文章來源:http://www.zghlxwxcb.cn/news/detail-711596.html
?文章來源地址http://www.zghlxwxcb.cn/news/detail-711596.html
到了這里,關(guān)于循序漸進(jìn)介紹基于CommunityToolkit.Mvvm 和HandyControl的WPF應(yīng)用端開發(fā)(7) -- 圖標(biāo)列表展示和選擇處理的文章就介紹完了。如果您還想了解更多內(nèi)容,請在右上角搜索TOY模板網(wǎng)以前的文章或繼續(xù)瀏覽下面的相關(guān)文章,希望大家以后多多支持TOY模板網(wǎng)!