2016-06-17 89 views
1

這是我的App.xaml文件(減少):添加前綴的ItemSource值組合框

<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和/或拼合屬性(格式爲0.000)。

+0

你真的硬編碼組合框條目或者他們通過'combobox.Items.Add'或插入'DataSource'? – pay

+0

目前,154個標題的大名單作爲資源在'app.xml'文件中。最終我需要支持**本地化**。我沒有使用'Add'函數調用。根據我的問題,我正在使用'ItemSource'。 –

+1

我可以建議將歌曲列表放入文件中,並在應用程序初始化時讀取該文件,然後通過Items.Add添加它們。這是一個非常簡單的解決方案來編號/索引您的條目。 – pay

回答

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> 

有一個很大的。你列出的是正確的。但是,如果您選擇一個項目,組合框也會顯示「001 - 耶和華的屬性」。要讓它只顯示「耶和華的屬性」,你需要修改控制模板。

+0

謝謝。用我的更新問題在XML中有兩個屬性。我們可以利用它嗎?我看到154個標題。所以如果我們可以結合格式化我的XML中的項目。我們是贏家。可行? –

+0

是的,但您確定要使用第二個屬性?這裏的想法是你不必手動設置數字。如果你將第100首歌曲移至第一首?你將不得不修復100首歌曲的號碼。 – user2880486

+0

排序不會改變。他們代表書中的歌曲。所以它是固定的。我寧願要管理一組數據。如果可能的話。 –

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 Song 1

2 Song 2

編輯:根據您的文章的最後一部分

最終,其他地方的應用程序,我會想從使用組合框中選擇指數拉出正確的歌名(無前綴)資源。

在您的例子,格式爲001 - Song 1

如果你只想歌名沒有前綴,由selectedIndex,你有幾種選擇。

1)你可以有一個第二個列表,你掙錢的時候,應用程序初始化,根本不包含前綴。編輯列表時,製作第二個列表,並添加沒有前綴的歌曲名稱。然後,您可以使用您的ComboBoxselectedIndex屬性來引用此列表。

2)您可以使用selectedIndex屬性,然後使用字符串操作的一些變化只提取歌曲名稱。

string[] selectedSong = combo1.Items[0].ToString().Split('-'); 

在這個例子中,沒有前綴的歌曲名稱會裏selectedSong[1]

+0

謝謝。我想要使​​用一個XML文件,然後將歌曲標題和歌曲編號作爲屬性。我只是希望如果數據被放入其他格式,如每個項目具有2個屬性的XML,我們仍然可以捆綁。我會看看你寫的tomorroe。另一方面是由於本地化,文件需要在資源中。 –

+1

是的,還有其他方法來存儲一些項目列表,這主要取決於您。但是,如果您卸載某種存儲方法而不是硬編碼,將項目放入組合框的方法通常就是這種方法。 – pay

+0

這也將使ComboBox.Text「1歌曲1」,「2歌曲2」等 – user2880486

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; } 
    } 
} 
+0

謝謝。我明天會看這個。看看我是否可以從XML文件資源中獲得填充的「SongList」。 –

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」

+0

我用我的問題。但我無法合併兩個屬性等。 –