亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb

首頁 > 編程 > C# > 正文

Winform開發框架中如何使用DevExpress的內置圖標資源

2019-10-29 19:41:07
字體:
來源:轉載
供稿:網友

前言

在開發Winform程序界面的時候,我們往往會使用一些較好看的圖表,以便能夠為我們的程序界面增色,良好的圖標設置可以讓界面看起來更加美觀舒服,而且也比較容易理解,圖標我們可以通過一些網站獲取各種場景的圖標資源,不過本篇隨筆主要介紹如何利用DevExpress的內置圖標資源來實現界面圖標的設置。

下面話不多說了,來一起看看詳細的介紹吧

1、設計時刻的圖標處理

豐富的圖標處理,在菜單、工具欄、樹列表等地方,以及按鈕等地方,都可以使用,而這些我們可以利用DevExpress的內置圖標選擇來減輕我們尋找合適圖標的煩惱。

Winform,開發框架,DevExpress,圖標資源

一些按鈕、工具欄等的圖標設置,一般是固定的,我們往往可以在設計時刻就指定它,這樣我們可以使用本地的圖標,也可以使用DevExpress的內置圖標。而使用DevExpress內置圖標資源的時候,我們可以調出DevExpress的內置圖標選擇框的。

如下是按鈕添加圖標方式,操作非常簡單,在按鈕的右上角小圖標上單擊一下進入編輯界面,如下所示。

Winform,開發框架,DevExpress,圖標資源

然后選擇Image按鈕,進入圖標選擇界面,選擇內置的DevExpress圖標庫即可,基本上,只要是DevExpress的原生控件,那么就可以通過這種內置圖標的對話框進行圖標選擇,非常方便。

Winform,開發框架,DevExpress,圖標資源

2、運行時刻的圖標處理

上面的操作是在設計時候,DevExpress設計器給我們提供很多便利選擇內置圖標,而在界面運行時刻,想動態處理界面按鈕圖標,或者樹形菜單的圖標的時候,就沒有這個直接的接口來設置圖標了,而我們框架的菜單往往都是需用動態增加的,因此圖標的設置也是在運行時刻的。如下面的樹列表中,圖標就是動態指定的。

Winform,開發框架,DevExpress,圖標資源

這些動態的樹形菜單,是在權限系統里面動態配置的,菜單的配置界面如下所示。

Winform,開發框架,DevExpress,圖標資源

上面的選擇圖圖標就是我們需要動態設置的圖標,由于圖標資源我們是以圖片形式存儲在對應的記錄里面的,因此使用起來也是比較方便的,我們在配置的時候,獲取到對應的圖標資源并存儲起來即可。

除了上面可以參考從DevExpress內置圖標資源獲取圖標的方式外

Winform,開發框架,DevExpress,圖標資源

我們還可以選擇我們自己喜歡的圖標資源,也就是從系統圖標文件中選擇自己喜歡的,如下界面所示。

Winform,開發框架,DevExpress,圖標資源

因此我考慮在運行時刻整合兩種不同選擇圖標的方式。

我們先來看看我整合后的圖表選擇界面,如下所示,包含了運行時刻提取DevExpress內置圖標的功能和從系統文件中選擇圖標的功能。

Winform,開發框架,DevExpress,圖標資源

3、運行時刻提取DevExpress內置圖標的功能實現

首先我們參考設計時刻的界面展示

Winform,開發框架,DevExpress,圖標資源

來設計一個界面來展示圖標信息

Winform,開發框架,DevExpress,圖標資源

參考原版的界面,設計盡可能貼近即可,另外我們自己加入一個從系統選擇圖標資源的操作。

Winform,開發框架,DevExpress,圖標資源

至于圖標選中后我們返回對應的Image對象給調用者,則通過事件進行處理,以便選中后,即使更新顯示效果。

如下所示,我們定義一個委托和事件。

/// <summary> /// DevExpress圖標和系統圖標選擇窗體 /// </summary> public partial class FrmImageGallery : BaseForm {  /// <summary>  /// 自定義一個委托處理圖標選擇  /// </summary>  public delegate void IconSelectHandlerDelegate(Image image, string name);  /// <summary>  /// 圖標選擇的事件  /// </summary>  public event IconSelectHandlerDelegate OnIconSelected;  private DXImageGalleryLoader loader = null;  public FrmImageGallery()  {   InitializeComponent();   InitDictItem();//初始化  }    /// <summary>  /// 處理圖標選擇的事件觸發  /// </summary>  public virtual void ProcessIconSelected(Image image, string name)  {   if (OnIconSelected != null)   {    OnIconSelected(image, name);   }  }

然后在內置圖標顯示中,如果觸發圖標的單擊,我們就觸發事件,以便讓調用者更新界面顯示,如下代碼所示。

foreach (GalleryItem item in items[key]){ item.ItemClick += (s, e) => {  //選擇處理  ProcessIconSelected(item.ImageOptions.Image, item.Description); };}

而對于從系統文件加載文件進行顯示圖標的,類似的觸發方式。

/// <summary>  /// 從系統資源中加載圖標文件,然后觸發事件進行顯示  /// </summary>  private void txtFilePath_Properties_ButtonClick(object sender, ButtonPressedEventArgs e)  {   string file = GetIconPath();   if (!string.IsNullOrEmpty(file))   {    this.txtFilePath.Text = file;//記錄文件名    this.txtEmbedIcon.Image = LoadIcon(file);//顯示圖片    this.txtEmbedIcon.Size = new System.Drawing.Size(64, 64);    //返回處理    ProcessIconSelected(this.txtEmbedIcon.Image, file);   }  }

這樣我們在菜單的選擇圖標的時候,就可以觸發事件進行獲取圖表并更新自身了。

Winform,開發框架,DevExpress,圖標資源

private void btnSelectIcon_Click(object sender, EventArgs e)  {   FrmImageGallery dlg = new FrmImageGallery();   dlg.OnIconSelected += (image, name) =>   {    this.txtEmbedIcon.Image = image;   };   dlg.ShowDialog();  }

完成了這些處理,我們再次將焦點放在如何提取并展示DevExpress內置圖標的身上。

Winform,開發框架,DevExpress,圖標資源

為了獲取圖表資源里面的分類及大小等信息,我們需要把圖標資源進行一個加載出來,然后讀取里面的類別和大小、集合等信息。先定義幾個變量來承載這些信息。

/// <summary>  /// 圖標分類  /// </summary>  public List<string> Categories { get; set; }  /// <summary>  /// 圖標集合  /// </summary>  public List<string> Collection { get; set; }  /// <summary>  /// 圖標尺寸  /// </summary>  public List<string> Size { get; set; }

我們知道,DevExpress的圖標資源在程序集DevExpress.Utils.DxImageAssemblyUtil.ImageAssembly里面,因此我們需要對它進行讀取,并依次對各個資源進行處理。

我們來看看具體的處理代碼,如下所示。

using (System.Resources.ResourceReader reader = GetResourceReader(DevExpress.Utils.DxImageAssemblyUtil.ImageAssembly))   {    System.Collections.IDictionaryEnumerator dict = reader.GetEnumerator();    while (dict.MoveNext())    {     string key = (string)dict.Key as string;     if (!DevExpress.Utils.DxImageAssemblyUtil.ImageProvider.IsBrowsable(key)) continue;     if (key.EndsWith(".png", StringComparison.Ordinal))     {      string reg = @"(?<collection>/S*?)/(?<category>/S*?)/(?<name>/S*)";      var collectionItem = CRegex.GetText(key, reg, "collection");       var categoryItem = CRegex.GetText(key, reg, "category");      string sizeReg = @"_(?<size>/S*)/.";      var sizeItem = CRegex.GetText(key, sizeReg, "size");      if (!this.Collection.Contains(collectionItem))      {       this.Collection.Add(collectionItem);      }      if (!this.Categories.Contains(categoryItem))      {       this.Categories.Add(categoryItem);      }      if (!this.Size.Contains(sizeItem))      {       this.Size.Add(sizeItem);      }      Image image = GetImageFromStream((System.IO.Stream)dict.Value);      if (image != null)      {       var item = new DevExpress.XtraBars.Ribbon.GalleryItem(image, key, key);       if (!ImageCollection.ContainsKey(key))       {        ImageCollection.Add(key, item);       }      }           }    }   }

其中讀取資源的操作代碼是

GetResourceReader(DevExpress.Utils.DxImageAssemblyUtil.ImageAssembly)

這個代碼它就是從資源里面進行獲取對應的圖表資源。

private System.Resources.ResourceReader GetResourceReader(System.Reflection.Assembly imagesAssembly)  {   var resources = imagesAssembly.GetManifestResourceNames();   var imageResources = Array.FindAll(resources, resourceName => resourceName.EndsWith(".resources"));   if (imageResources.Length != 1)   {    throw new Exception("讀取異常");   }   return new System.Resources.ResourceReader(imagesAssembly.GetManifestResourceStream(imageResources[0]));  }

另外,我們根據圖表的文件名結構,我們通過正則表達式來讀取它的對應信息,然后把它的大小、類別、集合信息存儲起來。

 string reg = @"(?<collection>/S*?)/(?<category>/S*?)/(?<name>/S*)"; var collectionItem = CRegex.GetText(key, reg, "collection");  var categoryItem = CRegex.GetText(key, reg, "category"); string sizeReg = @"_(?<size>/S*)/."; var sizeItem = CRegex.GetText(key, sizeReg, "size");

圖表信息讀取了,我們需要解析它然后存儲起來,把圖標的Image對象放在一個字典類別里面,方便按照組別進行展示。

Image image = GetImageFromStream((System.IO.Stream)dict.Value); if (image != null) {  var item = new DevExpress.XtraBars.Ribbon.GalleryItem(image, key, key);  if (!ImageCollection.ContainsKey(key))  {   ImageCollection.Add(key, item);  } }

有了這些資源,我們對它們進行搜索就顯得很方便了,我們如果需要根據文件名或者其他條件進行查詢集合的數據,提供一個通用的方法即可,如下代碼所示。

/// <summary>  /// 根據條件獲取集合  /// </summary>  /// <returns></returns>  public Dictionary<string, GalleryItemCollection> Search(List<string> collection, List<string> categories,    List<string> size, string fileName = "")  {   Dictionary<string, GalleryItemCollection> dict = new Dictionary<string, GalleryItemCollection>();   GalleryItemCollection list = new GalleryItemCollection();   foreach (var key in ImageCollection.Keys)   {    //使用正則表達式獲取圖標文件名中的集合、類別、大小等信息    string reg = @"(?<collection>/S*?)/(?<category>/S*?)/(?<name>/S*)";    var collectionItem = CRegex.GetText(key, reg, "collection");    var categoryItem = CRegex.GetText(key, reg, "category");    string sizeReg = @"_(?<size>/S*)/.";    var sizeItem = CRegex.GetText(key, sizeReg, "size");    //如果是查詢處理,把記錄放到查詢結果里面    if (!string.IsNullOrEmpty(fileName))    {     if(key.Contains(fileName))     {      list.Add(ImageCollection[key]);     }     dict["查詢結果"] = list;    }    else    {     //如果是集合和列表中包含的,把它們按類別添加到字典里面     if (collection.Contains(collectionItem) &&       categories.Contains(categoryItem) &&       size.Contains(sizeItem))     {      if (!dict.ContainsKey(categoryItem))      {       GalleryItemCollection cateList = new GalleryItemCollection();       cateList.Add(ImageCollection[key]);       dict[categoryItem] = cateList;      }      else      {       GalleryItemCollection cateList = dict[categoryItem];       cateList.Add(ImageCollection[key]);      }     }    }   }   return dict;  }

這次搜索就直接基于已有的集合ImageCollection進行搜索的了,不用再次讀取程序集并依次分析它,速度提供不少的。

由于圖表資源的處理是比較耗時的,我們把整個圖標加載的類作為一個靜態的對象緩存起來,這樣下次使用直接從緩存里面拿,對應的資源也不用重新加載,更好的提高我們重用的效果了,體驗更好了。

/// <summary> /// 圖標庫加載處理 /// </summary> public class DXImageGalleryLoader {  /// <summary>  /// 圖標字典類別集合  /// </summary>  public Dictionary<string, GalleryItem> ImageCollection { get; set; }  /// <summary>  /// 圖標分類  /// </summary>  public List<string> Categories { get; set; }  /// <summary>  /// 圖標集合  /// </summary>  public List<string> Collection { get; set; }  /// <summary>  /// 圖標尺寸  /// </summary>  public List<string> Size { get; set; }  /// <summary>  /// 使用緩存處理,獲得對象實例  /// </summary>  public static DXImageGalleryLoader Default  {   get   {    System.Reflection.MethodBase method = System.Reflection.MethodBase.GetCurrentMethod();    string keyName = string.Format("{0}-{1}", method.DeclaringType.FullName, method.Name);    var result = MemoryCacheHelper.GetCacheItem<DXImageGalleryLoader>(keyName,      delegate () { return new DXImageGalleryLoader().LoadData(); },      new TimeSpan(0, 30, 0));//30分鐘過期    return result;   }  }

以上代碼通過

public static DXImageGalleryLoader Default

定義了一個靜態的實例屬性,這樣這個DXImageGalleryLoader 實例只會在程序第一次使用的時候構建并加載圖片資源,后續都是從緩存里面讀取,提高響應速度的同時,也會記住上次的選擇界面內容。

以上就是整個功能的處理思路,以及一步步的優化處理,以便實現功能展示的同時,也提高響應速度,最終界面就是我們開始的時候介紹的那樣。

Winform,開發框架,DevExpress,圖標資源

Winform,開發框架,DevExpress,圖標資源

單擊或者選中系統圖標后, 需要設置的按鈕或者界面,就會及時更新圖標展示,體驗效果還是非常不錯的。

由于這個界面功能的通用性,我把它作為系統界面基礎模塊,放到了我的框架BaseUIDx里面,各個系統模塊都可以調用了。

總結

以上就是這篇文章的全部內容了,希望本文的內容對大家的學習或者工作具有一定的參考學習價值,如果有疑問大家可以留言交流,謝謝大家對VEVB武林網的支持。


注:相關教程知識閱讀請移步到c#教程頻道。
發表評論 共有條評論
用戶名: 密碼:
驗證碼: 匿名發表
亚洲香蕉成人av网站在线观看_欧美精品成人91久久久久久久_久久久久久久久久久亚洲_热久久视久久精品18亚洲精品_国产精自产拍久久久久久_亚洲色图国产精品_91精品国产网站_中文字幕欧美日韩精品_国产精品久久久久久亚洲调教_国产精品久久一区_性夜试看影院91社区_97在线观看视频国产_68精品久久久久久欧美_欧美精品在线观看_国产精品一区二区久久精品_欧美老女人bb
国自产精品手机在线观看视频| 国语自产精品视频在线看抢先版图片| 成人深夜直播免费观看| 中文字幕av一区中文字幕天堂| 成人情趣片在线观看免费| 亚洲大胆人体av| 一区二区三区黄色| 91视频免费在线| 国产一区二区色| 久久精品国产视频| 成人精品一区二区三区电影免费| 成人午夜在线影院| 亚洲情综合五月天| 1769国产精品| 久久亚洲一区二区三区四区五区高| 亚洲欧美日韩一区二区三区在线| 国产69精品99久久久久久宅男| 影音先锋欧美在线资源| 亚洲国产成人久久综合| 中文字幕欧美精品日韩中文字幕| 成人激情免费在线| 久久免费观看视频| 中文字幕亚洲综合久久筱田步美| 欧美在线精品免播放器视频| 欧美电影第一页| 欧美视频在线观看 亚洲欧| 欧美一二三视频| 国产精品久久久久高潮| 亚洲人午夜精品| 国产精品国产福利国产秒拍| 精品日本美女福利在线观看| 亚洲色图25p| 欧美成人h版在线观看| 亚洲人成在线免费观看| 亚洲精品有码在线| 色偷偷亚洲男人天堂| 欧美片一区二区三区| 国产欧美最新羞羞视频在线观看| 久久亚洲影音av资源网| 久久电影一区二区| 欧美亚洲激情在线| 欧美韩日一区二区| 国产在线久久久| 亚洲欧美资源在线| 久久久999成人| 欧美性色19p| 精品一区二区三区电影| 欧美激情一区二区三级高清视频| 一区二区三区四区精品| 亚洲精品suv精品一区二区| 中文字幕国产精品久久| 欧美日韩精品国产| 国产精品自产拍在线观看中文| 日韩亚洲国产中文字幕| 久久久久久久久91| 精品久久久久久久久中文字幕| 亚洲成人黄色网址| 成人情趣片在线观看免费| 欧美性视频网站| 日韩精品中文字幕在线观看| 日韩视频欧美视频| 另类专区欧美制服同性| 亚洲精品国产欧美| 亚洲一区二区三区sesese| 欧美中文在线观看| 国产专区精品视频| 狠狠躁夜夜躁久久躁别揉| 91亚洲精品久久久久久久久久久久| 在线播放精品一区二区三区| 国产成人精彩在线视频九色| 欧美成人午夜激情视频| 日韩美女福利视频| 国产精品吴梦梦| 亚洲精品一区二区三区不| 国产亚洲人成a一在线v站| 欧美在线视频一区二区| 尤物99国产成人精品视频| 亚洲国产天堂久久综合网| 青青草99啪国产免费| 伊人久久久久久久久久久| 国产精品视频公开费视频| 亚洲国产高清高潮精品美女| 国产精品久久久久久av福利软件| 国产精品一区二区久久国产| 狠狠躁夜夜躁人人爽超碰91| 啊v视频在线一区二区三区| 国产精品揄拍500视频| 超碰97人人做人人爱少妇| 久久久久久网站| 97在线看免费观看视频在线观看| 中文字幕久热精品在线视频| 久久久久久久一区二区| 日韩精品极品在线观看播放免费视频| 久久精品国产亚洲| 色小说视频一区| 欧美日韩在线第一页| 国内精品美女av在线播放| 欧美日韩免费区域视频在线观看| 日本久久久a级免费| 亚洲国产又黄又爽女人高潮的| 亚洲白拍色综合图区| 亚洲视频在线观看| 国语自产精品视频在线看一大j8| 欧美成人亚洲成人日韩成人| 美女国内精品自产拍在线播放| 久久久999国产精品| 国产精品99蜜臀久久不卡二区| 欧美在线播放视频| 国产婷婷97碰碰久久人人蜜臀| 亚洲第一色中文字幕| 韩日欧美一区二区| 黄色精品在线看| 亚洲视频第一页| 日韩欧美在线视频日韩欧美在线视频| 成人字幕网zmw| 91免费的视频在线播放| 美日韩精品免费观看视频| 国产精品视频中文字幕91| 国产成人拍精品视频午夜网站| 日韩中文字幕在线精品| 欧美黄色片免费观看| 久久综合国产精品台湾中文娱乐网| 久久成年人视频| 欧美极品美女视频网站在线观看免费| 欧美激情视频一区二区三区不卡| 尤物tv国产一区| 国产精品v日韩精品| 亚洲九九九在线观看| 色综合久综合久久综合久鬼88| 日韩二区三区在线| 538国产精品视频一区二区| 久久精品国产亚洲| 视频在线一区二区| 国产精品第一页在线| 另类图片亚洲另类| 欧美性猛交xxxx偷拍洗澡| 精品一区二区三区三区| 这里精品视频免费| 久久成年人视频| 成人国内精品久久久久一区| 亚洲一区二区免费| 一区二区三区动漫| 亚洲视频免费一区| 亚洲欧洲av一区二区| 日韩在线免费观看视频| 69久久夜色精品国产69| 日韩欧美在线看| 91国产美女在线观看| 色狠狠av一区二区三区香蕉蜜桃| 韩国欧美亚洲国产| 韩剧1988免费观看全集| 欧美大尺度电影在线观看| 日韩在线激情视频| 久久久久久久久久久久av| 欧美成人精品不卡视频在线观看| 亚洲欧美视频在线| 欧美成人午夜激情视频| 日韩美女av在线免费观看| 亚洲国语精品自产拍在线观看| 亚洲自拍另类欧美丝袜| 亚洲欧美国产日韩天堂区| 国内精品久久久久久久久| 亚洲网在线观看| 欧美日韩日本国产|