一、要实现的功能
在WPF中,一个正常的Combobox是长这样的:
当点击下拉框的时候,下拉列表就是简单的文本,看起来很单一。
这里我们给它加点料,让它变成这样:
就是给文本前面加个图标,这个图标可以根据item的属性更改,比如要素图层和独立表就可以用不同的图标来表示,让人一目了然。
二、实现方法
首先,正常的ComboBox代码长这样:
html
<ComboBox x:Name="combox_fc"
Margin="15,35,15,0"
VerticalAlignment="Top"
DropDownOpened="combox_fc_DropDown"/>
要更改下拉框的内容,需要修改【ItemTemplate】下的【DataTemplate】:
html
<ComboBox x:Name="combox_fc" Margin="15,35,15,0" VerticalAlignment="Top" DropDownOpened="combox_fc_DropDown">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="/CCTool;component/Data/Icons/layer.png" Width="16" Height="16"/>
<TextBlock Margin="5,0" Text="文本"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
【DataTemplate】下加入了一个Image用来放图标,TextBlock用来代替原来的Text。
但是这里的Image和TextBlock都被写死的,正常使用的时候,ComboBox的item是需要实时变化的。
最好的解决方法是将Image的Source值,以及TextBlock的Text值进行绑定,从而实现实时更新。
代码修改如下:
html
<ComboBox x:Name="combox_fc" Margin="15,35,15,0" VerticalAlignment="Top" DropDownOpened="combox_fc_DropDown">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Source="{Binding Path}" Width="16" Height="16"/>
<TextBlock Margin="5,0" Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
回到后端,首先定义一个类,用来储存上述两个绑定的属性:
cs
// 图层
public class FeatureLayerContent
{
public string Path { get; set; }
public string Name { get; set; }
}
例子里,ComboBox要获取的是当前地图中的所有要素图层和独立表:
cs
// 获取当前地图
Map map = MapView.Active.Map;
// 获取所有要素图层
List<FeatureLayer> featureLayers = map.GetLayersAsFlattenedList().OfType<FeatureLayer>().ToList();
// 获取所有独立表
List<StandaloneTable> standaloneTables = map.GetStandaloneTablesAsFlattenedList().ToList();
然后把图层名和图标的路径给新创建的FeatureLayerContent类:
cs
// 定义一个空包
List<FeatureLayerContent> flc = new List<FeatureLayerContent>();
// 图层和表的图标
string imagePath = "/CCTool;component/Data/Icons/layer.png";
string imagePath2 = "/CCTool;component/Data/Icons/table.png";
// 把图层和表加到combox中
foreach (string featureLayer in featureLayers)
{
flc.Add(new FeatureLayerContent() { Path = imagePath, Name = featureLayer });
}
foreach (var standaloneTable in standaloneTables)
{
flc.Add(new FeatureLayerContent() { Path = imagePath2, Name = standaloneTable });
}
最后一步绑定给ComboBox:
cs
// 应用
comboBox.ItemsSource = flc;
大功告成。