这是在我的app.xaml文件中(缩减):
<Application.Resources>
<x:Array x:Key="SongTitleString" Type="local:ComboBoxItemString">
<local:ComboBoxItemString ValueString = "Song 1"/>
<local:ComboBoxItemString ValueString = "Song 2"/>
<local:ComboBoxItemString ValueString = "Song 3"/>
</x:Array>
</Application.Resources>
这是班级:
namespace OCLMEditor
{
/// This class provides us with an object to fill a ComboBox with
/// that can be bound to string fields in the binding object.
public class ComboBoxItemString
{
public string ValueString { get; set; }
}
}
这是标记:
<ComboBox x:Name="comboSongOpen" ItemsSource="{StaticResource SongTitleString}"
DisplayMemberPath="ValueString"
SelectedValuePath="ValueString"
SelectedValue="{Binding SongTitle}">
<ComboBox.MaxWidth>
<Binding Path="ActualWidth"
ElementName="textWeeklyBibleReading"/>
</ComboBox.MaxWidth>
</ComboBox>
一切都好。这个问题是,当歌曲标题显示在组合上时,我想在歌曲标题前加一个3位数字。例如:
001 - Song 1 002 - Song 2 003 - Song 3
最终,在应用程序的其他地方,我会想要使用组合框选择索引从资源中提取出正确的歌曲标题(没有前缀)。
这可能吗?
更新
如果我创建XML:
<?xml version="1.0" encoding="utf-8" ?>
<Settings>
<SongTitles>
<SongTitle Number="1" Title = "Jehovah's Attributes"/>
</SongTitles>
</Settings>
并将其作为资源添加到WPF:
<Window.Resources>
<XmlDataProvider x:Key="XmlData" Source="OCLM_Resources.xml" XPath="Settings/SongTitles" />
</Window.Resources>
然后使用:
<ComboBox x:Name="comboSongOpen"
ItemsSource="{Binding Source={StaticResource XmlData}, XPath=./SongTitle}" DisplayMemberPath="@Title">
<ComboBox.MaxWidth>
<Binding Path="ActualWidth"
ElementName="textWeeklyBibleReading"/>
</ComboBox.MaxWidth>
</ComboBox>
显示标题中的标题。但我不能完全理解使用ItemTemplate
和/或stiching属性(格式化0.000)。
答案 0 :(得分:3)
这是一个非常简单的纯xaml解决方案。你不需要改变你拥有的任何东西。
//add this to your resource. Obviously you should put this in code if you have lots of items
<AlternationConverter x:Key="AlternateForegroundConverter">
<s:Int16>1</s:Int16>
<s:Int16>2</s:Int16>
<s:Int16>3</s:Int16>
<s:Int16>4</s:Int16>
<s:Int16>5</s:Int16>
//more if necessary
</AlternationConverter>
<ComboBox x:Name="comboSongOpen" ItemsSource="{StaticResource SongTitleString}" SelectedValuePath="ValueString" SelectedValue="{Binding SongTitle}" AlternationCount="99999" >
<ComboBox.ItemTemplate>
<DataTemplate DataType="local:ComboBoxItemString">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding (ItemsControl.AlternationIndex), RelativeSource={RelativeSource AncestorType=ListBoxItem}, StringFormat='000 - ', Converter={StaticResource AlternateForegroundConverter}}" />
<TextBlock Text="{Binding ValueString}" />
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
<ComboBox.MaxWidth>
<Binding Path="ActualWidth" ElementName="textWeeklyBibleReading"/>
</ComboBox.MaxWidth>
编辑:需要此命名空间
xmlns:s="clr-namespace:System;assembly=mscorlib"
编辑:回复更新的问题
将DataTemplate更改为(在这种情况下,您不需要AlternationConverter)。
<ComboBox.ItemTemplate>
<DataTemplate DataType="local:ComboBoxItemString">
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Number, StringFormat='000 - '}" />
<TextBlock Text="{Binding ValueString}" />
</StackPanel>
</DataTemplate>
//add Number property to you class
public class ComboBoxItemString
{
public string ValueString { get; set; }
public int Number { get; set; }
}
//add the array
<x:Array x:Key="SongTitleString" Type="local:ComboBoxItemString">
<local:ComboBoxItemString ValueString = "Song 1" Number = "1" />
<local:ComboBoxItemString ValueString = "Song 2" Number = "2" />
<local:ComboBoxItemString ValueString = "Song 3" Number = "3" />
</x:Array>
总有一个很大的问题。你的名单是正确的。但是如果你选择一个项目,ComboBox将显示&#34; 001 - 耶和华的属性&#34;同样。要让它显示出耶和华的属性&#34;只是,您需要修改控件模板。
答案 1 :(得分:2)
正如EdPlunkett建议的那样,使用ComboBox的ItemTemplate参考以下示例。
<Window x:Class="ChkList_Learning.Window2"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:local="clr-namespace:ChkList_Learning"
mc:Ignorable="d"
Title="Window2" Height="300" Width="300">
<Grid>
<StackPanel>
<ComboBox ItemsSource="{Binding SongList}" x:Name="songsCombo">
<ComboBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}"></TextBlock>
<TextBlock Text=" - "></TextBlock>
<TextBlock Text="{Binding SongName}"></TextBlock>
</StackPanel>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
<StackPanel Orientation="Horizontal">
<TextBlock Text="ID"></TextBlock>
<TextBox Width="100" Text="{Binding ElementName=songsCombo,Path=SelectedItem.Title}"></TextBox>
</StackPanel>
<StackPanel Orientation="Horizontal">
<TextBlock Text="Song Name"></TextBlock>
<TextBox Width="100" Text="{Binding ElementName=songsCombo,Path=SelectedItem.SongName}"></TextBox>
</StackPanel>
</StackPanel>
</Grid>
using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Shapes;
namespace ChkList_Learning
{
/// <summary>
/// Interaction logic for Window2.xaml
/// </summary>
public partial class Window2 : Window
{
public Window2()
{
InitializeComponent();
this.DataContext = new SongViewModel();
}
}
class SongViewModel
{
public ObservableCollection<Song> SongList { get; set; }
public SongViewModel()
{
SongList = new ObservableCollection<Song>();
for (int i = 0; i < 10; i++)
{
Song song = new Song();
song.Title = (i + 1).ToString();
song.SongName = "Song Name" + (i + 1).ToString();
song.AlbumName = "My Album";
SongList.Add(song);
}
}
}
class Song
{
public string Title { get; set; }
public string SongName { get; set; }
public string AlbumName { get; set; }
}
}
答案 2 :(得分:1)
我认为根据我对OP的评论,这更像是一个建议:
如果将歌曲列表卸载到文件中,则可以在初始化应用程序时读取文件以创建歌曲列表。文件的实际结构取决于您。通常使用CSV文件,因为这是一种分隔值(通过逗号)的简单方法,但您可以使用您喜欢的任何分隔符。
在这种情况下,考虑到一些简单的方法,你可以用C#读取文件,我甚至可以建议用新的行分隔你的歌曲名称。如果你这样做,编译你的歌曲列表就像这样简单:
string[] songList = System.IO.File.ReadAllLines(@"songlist.txt");
for (int i = 0; i < songList.Length; i++) {
string newItem = ((i+1).ToString()) + " " + songList[i];
combo1.Items.Add(newItem);
}
OR
List<string> songs = new List<string>();
for (int i = 0; i < songList.Length; i++) {
songs.Add((i + 1).ToString() + " " + songList[i]);
}
combo1.ItemsSource = songs;
因此在这些例子中,组合框的内容将是
1首歌1
2 Song 2
编辑:根据帖子的最后部分
最终,在应用程序的其他地方,我会想要使用组合框选择索引从资源中提取出正确的歌曲标题(没有前缀)。
在您的示例中,格式为001 - Song 1
如果你只想要没有前缀的歌曲标题,selectedIndex
,你有几个选择。
1)您可以在初始化应用程序时创建第二个列表,该列表不包含前缀。在编辑列表时,请创建第二个列表,然后添加不带前缀的歌曲名称。然后,您可以使用selectedIndex
的{{1}}属性来引用此列表。
2)您可以使用ComboBox
属性,然后使用一些字符串操作变体来提取歌曲名称。
selectedIndex
在此示例中,没有前缀的歌曲名称将位于string[] selectedSong = combo1.Items[0].ToString().Split('-');
内。
答案 3 :(得分:0)
只需添加一个带有前置
的DisplayMemberPath<Application.Resources>
<x:Array x:Key="SongTitleString" Type="local:ComboBoxItemString">
<local:ComboBoxItemString ValueString = "Song 1" ValueStringLong = "# 1 Song 1"/>
<local:ComboBoxItemString ValueString = "Song 2" ValueStringLong = "# 2 Song 1"/>
<local:ComboBoxItemString ValueString = "Song 3" ValueStringLong = "# 3 Song 1"/>
</x:Array>
</Application.Resources>
DisplayMemberPath =“ValueStringLong”