SilverLight中自定义图标控件
1. 建立一个用于读取资源的类SharedResources
using System;
using System.Collections.Generic;
using System.Diagnostics.CodeAnalysis;
using System.IO;
using System.Linq;
using System.Reflection;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Markup;
using System.Windows.Media.Imaging;
using System.Xml.Linq;
namespace System.Windows.Controls.Samples
{
/// <summary>
/// Utility to to load shared resources into another ResourceDictionary.
/// </summary>
public static class SharedResources
{
/// <summary>
/// Prefix of images loaded as resources.
///需要将资源嵌入,路径用命名空间的形式定义.
/// </summary>
private const string ResourceImagePrefix = "System.Windows.Controls.Samples.Images.";
/// <summary>
/// Prefix of icons loaded as resources.
///需要将资源嵌入,路径用命名空间的形式定义.
/// </summary>
private const string ResourceIconPrefix = "System.Windows.Controls.Samples.Icons.";
/// <summary>
/// Get an embedded resource image from the assembly.
/// </summary>
/// <param name="name">Name of the image resource.</param>
/// <returns>
/// Desired embedded resource image from the assembly.
/// </returns>
public static Image GetImage(string name)
{
return CreateImage(ResourceImagePrefix, name);
}
/// <summary>
/// Get an embedded resource icon from the assembly.
/// </summary>
/// <param name="name">Name of the icon resource.</param>
/// <returns>
/// Desired embedded resource icon from the assembly.
/// </returns>
public static Image GetIcon(string name)
{
return CreateImage(ResourceIconPrefix, name);
}
/// <summary>
/// A cached dictionary of the bitmap images.
/// </summary>
private static IDictionary<string, BitmapImage> cachedBitmapImages = new Dictionary<string, BitmapImage>();
/// <summary>
/// Get an embedded resource image from the assembly.
/// </summary>
/// <param name="prefix">The prefix of the full name of the resource.</param>
/// <param name="name">Name of the image resource.</param>
/// <returns>
/// Desired embedded resource image from the assembly.
/// </returns>
public static Image CreateImage(string prefix, string name)
{
Image image = new Image { Tag = name };
BitmapImage source = null;
string resourceName = prefix + name;
if (!cachedBitmapImages.TryGetValue(resourceName, out source))
{
Assembly assembly = typeof(SharedResources).Assembly;
using (Stream resource = assembly.GetManifestResourceStream(resourceName))
{
if (resource != null)
{
source = new BitmapImage();
source.SetSource(resource);
}
}
cachedBitmapImages[resourceName] = source;
}
image.Source = source;
return image;
}
/// <summary>
/// Get all of the names of embedded resources images in the assembly.
/// </summary>
/// <returns>
/// All of the names of embedded resources images in the assembly.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Does more work than a property should.")]
public static IEnumerable<string> GetImageNames()
{
return GetResourceNames(ResourceImagePrefix);
}
/// <summary>
/// Get all of the names of embedded resources icons in the assembly.
/// </summary>
/// <returns>
/// All of the names of embedded resources icons in the assembly.
/// </returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Does more work than a property should.")]
public static IEnumerable<string> GetIconNames()
{
return GetResourceNames(ResourceIconPrefix);
}
/// <summary>
/// Get all of the images in the assembly.
/// </summary>
/// <returns>All of the images in the assembly.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Does more work than a property should")]
public static IEnumerable<Image> GetImages()
{
foreach (string name in GetImageNames())
{
yield return GetImage(name);
}
}
/// <summary>
/// Get all of the icons in the assembly.
/// </summary>
/// <returns>All of the icons in the assembly.</returns>
[SuppressMessage("Microsoft.Design", "CA1024:UsePropertiesWhereAppropriate", Justification = "Does more work than a property should")]
public static IEnumerable<Image> GetIcons()
{
foreach (string name in GetIconNames())
{
yield return GetImage(name);
}
}
/// <summary>
/// Get all the names of embedded resources in the assembly with the
/// provided prefix value.
/// </summary>
/// <param name="prefix">The prefix for the full resource name.</param>
/// <returns>Returns an enumerable of all the resource names that match.</returns>
private static IEnumerable<string> GetResourceNames(string prefix)
{
Assembly assembly = typeof(SharedResources).Assembly;
foreach (string name in assembly.GetManifestResourceNames())
{
// Ignore resources that don't share the images prefix
if (!name.StartsWith(prefix, StringComparison.OrdinalIgnoreCase))
{
continue;
}
// Trim the prefix off of the name
yield return name.Substring(prefix.Length, name.Length - prefix.Length);
}
}
}
}
2. 定义节点SampleTreeItem
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Windows.Markup;
using System.Windows.Controls;
namespace System.Windows.Controls.Samples
{
/// <summary>
/// The SampleTreeItem represents a node in the TreeView.
/// </summary>
[ContentProperty("Items")]
public class SampleTreeItem
{
/// <summary>
/// Gets or sets the name of the TreeView node.
/// </summary>
public string TreeItemName { get; set; }
/// <summary>
/// Gets a collection of SampleTreeItems.
/// </summary>
public Collection<SampleTreeItem> Items { get; private set; }
/// <summary>
/// Initialize a SampleTreeItem.
/// </summary>
public SampleTreeItem()
{
Items = new Collection<SampleTreeItem>();
}
/// <summary>
/// Gets or sets the resource name of the Icon representing this
/// node.
/// </summary>
public string IconResourceName { get; set; }
/// <summary>
/// Gets the icon representing this type.
/// </summary>
public Image Icon
{
get
{
return SharedResources.GetIcon(IconResourceName);
}
}
}
}
3. 定义数据源,这里将数据写死在App.xaml中
<toolkit:ObjectCollection x:Key="SampleTreeView" xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation">
<samplesCommon:SampleTreeItem TreeItemName="Controls">
<samplesCommon:SampleTreeItem TreeItemName="Calendar" IconResourceName="Calendar.png"/>
<samplesCommon:SampleTreeItem TreeItemName="ChildWindow" IconResourceName="ChildWindow.png" />
<samplesCommon:SampleTreeItem TreeItemName="DatePicker" IconResourceName="DatePicker.png" />
<samplesCommon:SampleTreeItem TreeItemName="GridSplitter" IconResourceName="GridSplitter.png" />
<samplesCommon:SampleTreeItem TreeItemName="TabControl" IconResourceName="TabControl.png" />
<samplesCommon:SampleTreeItem TreeItemName="TreeView" IconResourceName="TreeView.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Data">
<samplesCommon:SampleTreeItem TreeItemName="DataGrid" IconResourceName="DataGrid.png" />
<samplesCommon:SampleTreeItem TreeItemName="DataPager" IconResourceName="DataPager.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="DataForm">
<samplesCommon:SampleTreeItem TreeItemName="DataForm" IconResourceName="DataForm.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Data Input">
<samplesCommon:SampleTreeItem TreeItemName="Validation" IconResourceName="ValidationSummary.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="DataVisualization">
<samplesCommon:SampleTreeItem TreeItemName="Area Series" IconResourceName="AreaSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Bar Series" IconResourceName="BarSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Bubble Series" IconResourceName="BubbleSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Column Series" IconResourceName="ColumnSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Line Series" IconResourceName="LineSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Pie Series" IconResourceName="PieSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Scatter Series" IconResourceName="ScatterSeries.png"/>
<samplesCommon:SampleTreeItem TreeItemName="TreeMap" IconResourceName="TreeMap.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Input">
<samplesCommon:SampleTreeItem TreeItemName="AutoCompleteBox" IconResourceName="AutoCompleteBox.png"/>
<samplesCommon:SampleTreeItem TreeItemName="ButtonSpinner" IconResourceName="ButtonSpinner.png"/>
<samplesCommon:SampleTreeItem TreeItemName="DomainUpDown" IconResourceName="DomainUpDown.png"/>
<samplesCommon:SampleTreeItem TreeItemName="NumericUpDown" IconResourceName="NumericUpDown.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Rating" IconResourceName="Rating.png"/>
<samplesCommon:SampleTreeItem TreeItemName="TimePicker" IconResourceName="TimePicker.png"/>
<samplesCommon:SampleTreeItem TreeItemName="UpDownBase" IconResourceName="UpDownBase.png"/>
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Layout">
<samplesCommon:SampleTreeItem TreeItemName="Accordion" IconResourceName="Accordion.png" />
<samplesCommon:SampleTreeItem TreeItemName="TransitioningContentControl" IconResourceName="TransitioningContentControl.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Navigation">
<samplesCommon:SampleTreeItem TreeItemName="Navigation" IconResourceName="Page.png" />
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Theming">
<samplesCommon:SampleTreeItem TreeItemName="ImplicitStyleManager" IconResourceName="ImplicitStyleManager.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Theme Browser" IconResourceName="ThemeBrowser.png"/>
</samplesCommon:SampleTreeItem>
<samplesCommon:SampleTreeItem TreeItemName="Toolkit">
<samplesCommon:SampleTreeItem TreeItemName="DockPanel" IconResourceName="DockPanel.png" />
<samplesCommon:SampleTreeItem TreeItemName="Expander" IconResourceName="Expander.png" />
<samplesCommon:SampleTreeItem TreeItemName="GlobalCalendar" IconResourceName="Calendar.png"/>
<samplesCommon:SampleTreeItem TreeItemName="Viewbox" IconResourceName="ViewBox.png" />
<samplesCommon:SampleTreeItem TreeItemName="WrapPanel" IconResourceName="WrapPanel.png" />
</samplesCommon:SampleTreeItem>
</toolkit:ObjectCollection>
4. 调用生成带图标节点的树
using System;
using System.Windows;
using System.Collections.Generic;
using System.Linq;
namespace System.Windows.Controls.Samples
{
/// <summary>
/// System.Windows.Controls samples application.
/// </summary>
public partial class App : Application
{
/// <summary>
/// Initializes a new instance of the App class.
/// </summary>
public App()
{
Startup += delegate
{
RootVisual = new SampleBrowser(this.GetType().Assembly, SampleTreeItems);
};
InitializeComponent();
}
/// <summary>
/// Gets a collection of SampleTreeItems to populate the SampleBrowser TreeView.
/// </summary>
public static IEnumerable<SampleTreeItem> SampleTreeItems
{
get
{
IEnumerable<object> data = Application.Current.Resources["SampleTreeView"] as IEnumerable<object>;
return (data != null) ?
data.OfType<SampleTreeItem>() :
Enumerable.Empty<SampleTreeItem>();
}
}
}
}
5.注意事项
SharedResources和SampleTreeItem需要与图标放在同一个项目里,图标需要嵌入到资源,而调用的程序可以在别的项目。
同一个程序可以有多个项目,每个项目可以有自已的“程序集名称”,
但项目间应该使用同一套“命名空间”,也就是说,不同项目间的“命名空间”不可以有重复.
如“程序集名称”可以分别定义成:
System.Windows.Controls.Samples
System.Windows.Controls.Samples.Common
但它们的默认“命名空间”都是System.Windows.Controls.Samples
总之,程序集名称是用来管理文件的(不一定是层次结构)。而命名空间才是用来管理代码的层次结构的。
为什么会这么设计呢。
有时候一个命名空间(一般对应一个文件夹)中的内容可能会很多,这时我们就需要把它拆分成不同的程序集。以便于管理。而有时候呢,代码量很少,不同的命名空间就直接放在一个文件中了。
真正使用时,
一个文件夹对应一个命名空间。如果不同的程序集使用的是同一个命名空间,那么他们应该可以放在同一个文件夹中。也就时说相同命名空间的项目之间,它们的第一级文件及文件夹的名称不可以有重复的。