一、需要的前提文件
從網上下載Emoji的表情包,當然是png的圖片,因為WPF不支持彩色的Emoji,所以,做列表的時候,需要用圖片。
隨著壓縮包一起的還有一個Emoji.xml文件,文件的層級結構如下
<array>
<dict>
<key></key>
<array>
<e></e>
<array>
</dict>
</array>
其實我們需要的知識<e></e>中間的內容。
<?xml version="1.0" encoding="utf-8" ?> <array> <dict> <key>nature</key> <array> <e>2600</e> <e>2614</e> <e>2601</e> <e>26c4</e> <e>1f319</e> <e>26a1</e> <e>1f300</e> <e>1f30a</e> <e>1f431</e> <e>1f436</e> <e>1f42d</e> <e>1f439</e> <e>1f430</e> <e>1f43a</e> <e>1f438</e> <e>1f42f</e> <e>1f428</e> <e>1f43b</e> <e>1f437</e> <e>1f42e</e> <e>1f417</e> <e>1f435</e> <e>1f412</e> <e>1f434</e> <e>1f40e</e> <e>1f42b</e> <e>1f411</e> <e>1f418</e> <e>1f40d</e> <e>1f426</e> <e>1f424</e> <e>1f414</e> <e>1f427</e> <e>1f41b</e> <e>1f419</e> <e>1f420</e> <e>1f41f</e> <e>1f433</e> <e>1f42c</e> <e>1f490</e> <e>1f338</e> <e>1f337</e> <e>1f340</e> <e>1f339</e> <e>1f33b</e> <e>1f33a</e> <e>1f341</e> <e>1f343</e> <e>1f342</e> <e>1f334</e> <e>1f335</e> <e>1f33e</e> <e>1f41a</e> </array> </dict> <dict> <key>objects</key> <array> <e>1f38d</e> <e>1f49d</e> <e>1f38e</e> <e>1f392</e> <e>1f393</e> <e>1f38f</e> <e>1f386</e> <e>1f387</e> <e>1f390</e> <e>1f391</e> <e>1f383</e> <e>1f47b</e> <e>1f385</e> <e>1f384</e> <e>1f381</e> <e>1f514</e> <e>1f389</e> <e>1f388</e> <e>1f4bf</e> <e>1f4c0</e> <e>1f4f7</e> <e>1f3a5</e> <e>1f4bb</e> <e>1f4fa</e> <e>1f4f1</e> <e>1f4e0</e> <e>260e</e> <e>1f4bd</e> <e>1f4fc</e> <e>1f50a</e> <e>1f4e2</e> <e>1f4e3</e> <e>1f4fb</e> <e>1f4e1</e> <e>27bf</e> <e>1f50d</e> <e>1f513</e> <e>1f512</e> <e>1f511</e> <e>2702</e> <e>1f528</e> <e>1f4a1</e> <e>1f4f2</e> <e>1f4e9</e> <e>1f4eb</e> <e>1f4ee</e> <e>1f6c0</e> <e>1f6bd</e> <e>1f4ba</e> <e>1f4b0</e> <e>1f531</e> <e>1f6ac</e> <e>1f4a3</e> <e>1f52b</e> <e>1f48a</e> <e>1f489</e> <e>1f3c8</e> <e>1f3c0</e> <e>26bd</e> <e>26be</e> <e>1f3be</e> <e>26f3</e> <e>1f3b1</e> <e>1f3ca</e> <e>1f3c4</e> <e>1f3bf</e> <e>2660</e> <e>2665</e> <e>2663</e> <e>2666</e> <e>1f3c6</e> <e>1f47e</e> <e>1f3af</e> <e>1f004</e> <e>1f3ac</e> <e>1f4dd</e> <e>1f4d6</e> <e>1f3a8</e> <e>1f3a4</e> <e>1f3a7</e> <e>1f3ba</e> <e>1f3b7</e> <e>1f3b8</e> <e>303d</e> <e>1f45f</e> <e>1f461</e> <e>1f460</e> <e>1f462</e> <e>1f455</e> <e>1f454</e> <e>1f457</e> <e>1f458</e> <e>1f459</e> <e>1f380</e> <e>1f3a9</e> <e>1f451</e> <e>1f452</e> <e>1f302</e> <e>1f4bc</e> <e>1f45c</e> <e>1f484</e> <e>1f48d</e> <e>1f48e</e> <e>2615</e> <e>1f375</e> <e>1f37a</e> <e>1f37b</e> <e>1f378</e> <e>1f376</e> <e>1f374</e> <e>1f354</e> <e>1f35f</e> <e>1f35d</e> <e>1f35b</e> <e>1f371</e> <e>1f363</e> <e>1f359</e> <e>1f358</e> <e>1f35a</e> <e>1f35c</e> <e>1f372</e> <e>1f35e</e> <e>1f373</e> <e>1f362</e> <e>1f361</e> <e>1f366</e> <e>1f367</e> <e>1f382</e> <e>1f370</e> <e>1f34e</e> <e>1f34a</e> <e>1f349</e> <e>1f353</e> <e>1f346</e> <e>1f345</e> </array> </dict> <dict> <key>people</key> <array> <e>1f604</e> <e>1f60a</e> <e>1f603</e> <e>263a</e> <e>1f609</e> <e>1f60d</e> <e>1f618</e> <e>1f61a</e> <e>1f633</e> <e>1f60c</e> <e>1f601</e> <e>1f61c</e> <e>1f61d</e> <e>1f612</e> <e>1f60f</e> <e>1f613</e> <e>1f614</e> <e>1f61e</e> <e>1f616</e> <e>1f625</e> <e>1f630</e> <e>1f628</e> <e>1f623</e> <e>1f622</e> <e>1f62d</e> <e>1f602</e> <e>1f632</e> <e>1f631</e> <e>1f620</e> <e>1f621</e> <e>1f62a</e> <e>1f637</e> <e>1f47f</e> <e>1f47d</e> <e>1f49b</e> <e>1f499</e> <e>1f49c</e> <e>1f497</e> <e>1f49a</e> <e>2764</e> <e>1f494</e> <e>1f493</e> <e>1f498</e> <e>2728</e> <e>1f31f</e> <e>1f4a2</e> <e>2755</e> <e>2754</e> <e>1f4a4</e> <e>1f4a8</e> <e>1f4a6</e> <e>1f3b6</e> <e>1f3b5</e> <e>1f525</e> <e>1f4a9</e> <e>1f44d</e> <e>1f44e</e> <e>1f44c</e> <e>1f44a</e> <e>270a</e> <e>270c</e> <e>1f44b</e> <e>270b</e> <e>1f450</e> <e>1f446</e> <e>1f447</e> <e>1f449</e> <e>1f448</e> <e>1f64c</e> <e>1f64f</e> <e>261d</e> <e>1f44f</e> <e>1f4aa</e> <e>1f6b6</e> <e>1f3c3</e> <e>1f46b</e> <e>1f483</e> <e>1f46f</e> <e>1f646</e> <e>1f645</e> <e>1f481</e> <e>1f647</e> <e>1f48f</e> <e>1f491</e> <e>1f486</e> <e>1f487</e> <e>1f485</e> <e>1f466</e> <e>1f467</e> <e>1f469</e> <e>1f468</e> <e>1f476</e> <e>1f475</e> <e>1f474</e> <e>1f471</e> <e>1f472</e> <e>1f473</e> <e>1f477</e> <e>1f46e</e> <e>1f47c</e> <e>1f478</e> <e>1f482</e> <e>1f480</e> <e>1f463</e> <e>1f48b</e> <e>1f444</e> <e>1f442</e> <e>1f440</e> <e>1f443</e> </array> </dict> <dict> <key>places</key> <array> <e>1f3e0</e> <e>1f3eb</e> <e>1f3e2</e> <e>1f3e3</e> <e>1f3e5</e> <e>1f3e6</e> <e>1f3ea</e> <e>1f3e9</e> <e>1f3e8</e> <e>1f492</e> <e>26ea</e> <e>1f3ec</e> <e>1f307</e> <e>1f306</e> <e>1f3e7</e> <e>1f3ef</e> <e>1f3f0</e> <e>26fa</e> <e>1f3ed</e> <e>1f5fc</e> <e>1f5fb</e> <e>1f304</e> <e>1f305</e> <e>1f303</e> <e>1f5fd</e> <e>1f308</e> <e>1f3a1</e> <e>26f2</e> <e>1f3a2</e> <e>1f6a2</e> <e>1f6a4</e> <e>26f5</e> <e>2708</e> <e>1f680</e> <e>1f6b2</e> <e>1f699</e> <e>1f697</e> <e>1f695</e> <e>1f68c</e> <e>1f693</e> <e>1f692</e> <e>1f691</e> <e>1f69a</e> <e>1f683</e> <e>1f689</e> <e>1f684</e> <e>1f685</e> <e>1f3ab</e> <e>26fd</e> <e>1f6a5</e> <e>26a0</e> <e>1f6a7</e> <e>1f530</e> <e>1f3b0</e> <e>1f68f</e> <e>1f488</e> <e>2668</e> <e>1f3c1</e> <e>1f38c</e> <e>1f1ef_1f1f5</e> <e>1f1f0_1f1f7</e> <e>1f1e8_1f1f3</e> <e>1f1fa_1f1f8</e> <e>1f1eb_1f1f7</e> <e>1f1ea_1f1f8</e> <e>1f1ee_1f1f9</e> <e>1f1f7_1f1fa</e> <e>1f1ec_1f1e7</e> <e>1f1e9_1f1ea</e> </array> </dict> <dict> <key>symbols</key> <array> <e>0031_20e3</e> <e>0032_20e3</e> <e>0033_20e3</e> <e>0034_20e3</e> <e>0035_20e3</e> <e>0036_20e3</e> <e>0037_20e3</e> <e>0038_20e3</e> <e>0039_20e3</e> <e>0030_20e3</e> <e>0023_20e3</e> <e>2b06</e> <e>2b07</e> <e>2b05</e> <e>27a1</e> <e>2197</e> <e>2196</e> <e>2198</e> <e>2199</e> <e>25c0</e> <e>25b6</e> <e>23ea</e> <e>23e9</e> <e>1f197</e> <e>1f195</e> <e>1f51d</e> <e>1f199</e> <e>1f192</e> <e>1f3a6</e> <e>1f201</e> <e>1f4f6</e> <e>1f235</e> <e>1f233</e> <e>1f250</e> <e>1f239</e> <e>1f22f</e> <e>1f23a</e> <e>1f236</e> <e>1f21a</e> <e>1f237</e> <e>1f238</e> <e>1f202</e> <e>1f6bb</e> <e>1f6b9</e> <e>1f6ba</e> <e>1f6bc</e> <e>1f6ad</e> <e>1f17f</e> <e>267f</e> <e>1f687</e> <e>1f6be</e> <e>3299</e> <e>3297</e> <e>1f51e</e> <e>1f194</e> <e>2733</e> <e>2734</e> <e>1f49f</e> <e>1f19a</e> <e>1f4f3</e> <e>1f4f4</e> <e>1f4b9</e> <e>1f4b1</e> <e>2648</e> <e>2649</e> <e>264a</e> <e>264b</e> <e>264c</e> <e>264d</e> <e>264e</e> <e>264f</e> <e>2650</e> <e>2651</e> <e>2652</e> <e>2653</e> <e>26ce</e> <e>1f52f</e> <e>1f170</e> <e>1f171</e> <e>1f18e</e> <e>1f17e</e> <e>1f532</e> <e>1f534</e> <e>1f533</e> <e>1f55b</e> <e>1f550</e> <e>1f551</e> <e>1f552</e> <e>1f553</e> <e>1f554</e> <e>1f555</e> <e>1f556</e> <e>1f557</e> <e>1f558</e> <e>1f559</e> <e>1f55a</e> <e>2b55</e> <e>274c</e> <e>00a9</e> <e>00ae</e> <e>2122</e> </array> </dict> </array>Emoji.xml
二、解析文件
xml文件其實就是對壓縮包裡的png圖片的一個分組,既然知道是做這個用的,則可以進行讀取xml,並獲取列表內容。
獲取內容之前,要先根據建立一個實體,實體的內容寫了三個字段key,keyimg(內容的第一個Emoji),EmojiCode
public class emojiEntity { private string _key;//分組 private string _keyImg;//分組圖像 private Dictionary<string, string> _emojiCode = new Dictionary<string, string>();//emoji編碼 /// <summary> /// 分組 /// </summary> public string Key { get { return _key; } set { _key = value; } } /// <summary> /// emoji編碼 /// </summary> public Dictionary<string, string> EmojiCode { get { return _emojiCode; } set { _emojiCode = value; } } /// <summary> /// 分組圖像 /// </summary> public string KeyImg { get { return _keyImg = EmojiCode.Values.First(); } } }emojiEntity
讀取xml文件,並寫入到List集合中
private List<emojiEntity> emojiList = new List<emojiEntity>(); /// <summary> /// emoji集合 /// </summary> public List<emojiEntity> EmojiList { get { return emojiList; } set { emojiList = value; } } /// <summary> /// 解析xml /// </summary> public void AnayXML() { XmlDocument xmlDoc = new XmlDocument(); xmlDoc.Load(Path.Combine(Environment.CurrentDirectory,@"Emoji.xml")); XmlNode root = xmlDoc.SelectSingleNode("array"); XmlNodeList nodeList = root.ChildNodes; foreach (XmlNode xn in nodeList) { XmlElement xe = (XmlElement)xn; XmlNodeList subList = xe.ChildNodes; emojiEntity entity = new emojiEntity(); foreach (XmlNode xmlNode in subList) { if (xmlNode.Name== "key") { entity.Key = xmlNode.InnerText; } if (xmlNode.Name== "array") { XmlElement lastXe = (XmlElement)xmlNode; foreach (XmlNode lastNode in lastXe) { if (lastNode.Name=="e") { entity.EmojiCode.Add(lastNode.InnerText,GetEmojiPath(lastNode.InnerText)); } } } } EmojiList.Add(entity); } } /// <summary> /// 返回Emoji路徑 /// </summary> /// <param name="name"></param> /// <returns></returns> private string GetEmojiPath(string name) { return "../image/"+"emoji_" + name + ".png"; }解析文件
三、寫ListBox和TabControl樣式
<SolidColorBrush x:Key="TabControlNormalBorderBrush" Color="#8C8E94"/> <SolidColorBrush x:Key="TabItemHotBorderBrush" Color="#3C7FB1"/> <SolidColorBrush x:Key="TabItemSelectedBackground" Color="#F9F9F9"/> <SolidColorBrush x:Key="TabItemDisabledBackground" Color="#F4F4F4"/> <SolidColorBrush x:Key="TabItemDisabledBorderBrush" Color="#FFC9C7BA"/> <Style x:Key="TabItemFocusVisual"> <Setter Property="Control.Template"> <Setter.Value> <ControlTemplate> <Rectangle Margin="3,3,3,1" SnapsToDevicePixels="true" Stroke="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" StrokeThickness="1" StrokeDashArray="1 2"/> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="TabItemStyle1" TargetType="{x:Type TabItem}"> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Disabled"/> <Setter Property="Background" Value="White"/> <Setter Property="FocusVisualStyle" Value="{StaticResource TabItemFocusVisual}"/> <Setter Property="Foreground" Value="Black"/> <Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/> <Setter Property="HorizontalContentAlignment" Value="Stretch"/> <Setter Property="VerticalContentAlignment" Value="Stretch"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TabItem}"> <Grid SnapsToDevicePixels="true"> <Grid.ColumnDefinitions> <ColumnDefinition Width="42*"/> <ColumnDefinition Width="55*"/> </Grid.ColumnDefinitions> <Border Background="WhiteSmoke" x:Name="Bd" BorderBrush="{TemplateBinding BorderBrush}" Padding="{TemplateBinding Padding}" Grid.ColumnSpan="2"> <Grid> <ContentPresenter x:Name="Content" ContentSource="Header" HorizontalAlignment="{Binding HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" RecognizesAccessKey="True" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" VerticalAlignment="{Binding VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}"/> </Grid> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="IsSelected" Value="true"> <Setter Property="Panel.ZIndex" Value="1"/> <Setter Property="Background" TargetName="Bd" Value="White"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="false"/> <Condition Property="IsMouseOver" Value="true"/> </MultiTrigger.Conditions> <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemHotBorderBrush}"/> </MultiTrigger> <Trigger Property="TabStripPlacement" Value="Bottom"> <Setter Property="BorderThickness" TargetName="Bd" Value="0"/> </Trigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="TabStripPlacement" Value="Top"/> </MultiTrigger.Conditions> <Setter Property="Margin" Value="-2,-2,-2,-1"/> <Setter Property="Margin" TargetName="Content" Value="0,0,0,1"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="TabStripPlacement" Value="Bottom"/> </MultiTrigger.Conditions> <Setter Property="Margin" Value="-2,-1,-2,-2"/> <Setter Property="Margin" TargetName="Content" Value="0,1,0,0"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="TabStripPlacement" Value="Left"/> </MultiTrigger.Conditions> <Setter Property="Margin" Value="-2,-2,-1,-2"/> <Setter Property="Margin" TargetName="Content" Value="0,0,1,0"/> </MultiTrigger> <MultiTrigger> <MultiTrigger.Conditions> <Condition Property="IsSelected" Value="true"/> <Condition Property="TabStripPlacement" Value="Right"/> </MultiTrigger.Conditions> <Setter Property="Margin" Value="-1,-2,-2,-2"/> <Setter Property="Margin" TargetName="Content" Value="1,0,0,0"/> </MultiTrigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Background" TargetName="Bd" Value="{StaticResource TabItemDisabledBackground}"/> <Setter Property="BorderBrush" TargetName="Bd" Value="{StaticResource TabItemDisabledBorderBrush}"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="TabControlStyle1" TargetType="{x:Type TabControl}"> <Setter Property="TabStripPlacement" Value="Bottom"/> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="BorderBrush" Value="{StaticResource TabControlNormalBorderBrush}"/> <Setter Property="Background" Value="White"/> <Setter Property="HorizontalContentAlignment" Value="Center"/> <Setter Property="VerticalContentAlignment" Value="Center"/> <Setter Property="Template"> <Setter.Value> <ControlTemplate TargetType="{x:Type TabControl}"> <Grid ClipToBounds="true" SnapsToDevicePixels="true" KeyboardNavigation.TabNavigation="Local"> <Grid.ColumnDefinitions> <ColumnDefinition x:Name="ColumnDefinition0"/> <ColumnDefinition x:Name="ColumnDefinition1" Width="0"/> </Grid.ColumnDefinitions> <Grid.RowDefinitions> <RowDefinition x:Name="RowDefinition0" Height="Auto"/> <RowDefinition x:Name="RowDefinition1" Height="*"/> </Grid.RowDefinitions> <TabPanel Background="WhiteSmoke" x:Name="HeaderPanel" Grid.Column="0" IsItemsHost="true" Margin="2,2,2,0" Grid.Row="0" KeyboardNavigation.TabIndex="1" Panel.ZIndex="1"/> <Border x:Name="ContentPanel" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Background="{TemplateBinding Background}" Grid.Column="0" KeyboardNavigation.DirectionalNavigation="Contained" Grid.Row="1" KeyboardNavigation.TabIndex="2" KeyboardNavigation.TabNavigation="Local"> <ContentPresenter x:Name="PART_SelectedContentHost" ContentSource="SelectedContent" Margin="{TemplateBinding Padding}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}"/> </Border> </Grid> <ControlTemplate.Triggers> <Trigger Property="TabStripPlacement" Value="Bottom"> <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="1"/> <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/> <Setter Property="Height" TargetName="RowDefinition0" Value="*"/> <Setter Property="Height" TargetName="RowDefinition1" Value="Auto"/> <Setter Property="Margin" TargetName="HeaderPanel" Value="2,0,2,2"/> </Trigger> <Trigger Property="TabStripPlacement" Value="Left"> <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/> <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/> <Setter Property="Grid.Column" TargetName="HeaderPanel" Value="0"/> <Setter Property="Grid.Column" TargetName="ContentPanel" Value="1"/> <Setter Property="Width" TargetName="ColumnDefinition0" Value="Auto"/> <Setter Property="Width" TargetName="ColumnDefinition1" Value="*"/> <Setter Property="Height" TargetName="RowDefinition0" Value="*"/> <Setter Property="Height" TargetName="RowDefinition1" Value="0"/> <Setter Property="Margin" TargetName="HeaderPanel" Value="2,2,0,2"/> </Trigger> <Trigger Property="TabStripPlacement" Value="Right"> <Setter Property="Grid.Row" TargetName="HeaderPanel" Value="0"/> <Setter Property="Grid.Row" TargetName="ContentPanel" Value="0"/> <Setter Property="Grid.Column" TargetName="HeaderPanel" Value="1"/> <Setter Property="Grid.Column" TargetName="ContentPanel" Value="0"/> <Setter Property="Width" TargetName="ColumnDefinition0" Value="*"/> <Setter Property="Width" TargetName="ColumnDefinition1" Value="Auto"/> <Setter Property="Height" TargetName="RowDefinition0" Value="*"/> <Setter Property="Height" TargetName="RowDefinition1" Value="0"/> <Setter Property="Margin" TargetName="HeaderPanel" Value="0,2,2,2"/> </Trigger> <Trigger Property="IsEnabled" Value="false"> <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}"/> </Trigger> </ControlTemplate.Triggers> </ControlTemplate> </Setter.Value> </Setter> </Style> <Style x:Key="WrapListBox" TargetType="ListBox"> <Setter Property="Background" Value="Transparent"/> <Setter Property="BorderThickness" Value="0"/> <Setter Property="ScrollViewer.HorizontalScrollBarVisibility" Value="Disabled"/> <Setter Property="ScrollViewer.VerticalScrollBarVisibility" Value="Hidden"/> <Setter Property="ItemsPanel"> <Setter.Value> <ItemsPanelTemplate> <WrapPanel/> </ItemsPanelTemplate> </Setter.Value> </Setter> <Setter Property="ItemTemplate"> <Setter.Value> <DataTemplate> <Grid> <Image Source="{Binding Path=Value}" Width="24" Height="24" Stretch="Uniform"/> </Grid> </DataTemplate> </Setter.Value> </Setter> </Style>ListBox和TabControl樣式
四、綁定數據
<TabControl SelectedIndex="0" ItemsSource="{Binding EmojiList,RelativeSource={RelativeSource Mode=FindAncestor,AncestorType=Window}}" ItemContainer> <TabControl.ItemTemplate> <DataTemplate> <Image Source="{Binding KeyImg}" Width="30" Height="30"/> </DataTemplate> </TabControl.ItemTemplate> <TabControl.ContentTemplate> <DataTemplate DataType="TabItem"> <ListBox ItemsSource="{Binding EmojiCode}" /> </DataTemplate> </TabControl.ContentTemplate> </TabControl>數據綁定
五、效果圖