2010-05-14 63 views
4

我有一個組合框,我想要顯示對象並返回枚舉值。當第一次打開時,組合框將按照設想顯示項目,但在選擇一個值後,它似乎從列表中消失。但是,如果組合框處於活動狀態,我可以使用鍵盤在其他值之間進行上下導航,因此它們位於列表中,但只能隱藏。當用於顯示對象時,組合框值將消失

我創建了一個小測試應用程序來顯示我的問題。當啓動應用程序顯示了所有的選擇組合框(前兩個是對象的類型,第三個是一個字符串):

All choices shown on startup http://i42.tinypic.com/ak7rll.png

選擇了藍線之後,當組合框再次此打開行缺少:

Blue line selected and is missing in popup http://i41.tinypic.com/24awgth.png

當選擇文本「綠色」的行線仍呈現:

Green line selected and still shown in popup http://i41.tinypic.com/2en3g2r.png

如果我選擇了紅線,唯一仍在列表中的是測試「綠色」。

我正在使用.NET Framework 3.5。

爲什麼元素消失的任何提示或提示?


以下是在Visual Studio中啓動空白項目後所需的所有代碼。

MainWindow.xaml.cs:

using System; 
using System.Collections.Generic; 
using System.Diagnostics; 

namespace Test 
{ 
    public partial class MainWindow 
    { 
     public MainWindow() 
     { 
     InitializeComponent(); 
     } 

     private ColorComboBoxValue _activeColor; 
     public ColorComboBoxValue ActiveColor 
     { 
     get { return _activeColor; } 
     set 
     { 
      _activeColor = value; 
      Debug.WriteLine("ActiveColor: " + _activeColor.Color); 
     } 
     } 
    } 

    public class ColorList : List<ColorComboBoxValue> { } 

    public class ColorComboBoxValue 
    { 
     public Color Color { get; set; } 
     public Object Object { get; set; } 
    } 

    public enum Color 
    { 
     Red, 
     Blue, 
     Green 
    } 
} 

MainWindow.xaml:

<Window x:Class="Test.MainWindow" x:Name="window" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     xmlns:System="clr-namespace:System;assembly=mscorlib" 
     xmlns:local="clr-namespace:Test" 
     Title="ComboBoxTest" Height="100" Width="200"> 

    <Window.Resources> 
     <local:ColorList x:Key="ColorList"> 
      <local:ColorComboBoxValue Color="Red"> 
       <local:ColorComboBoxValue.Object> 
        <Path Data="M0,0 L0,30 60,30 60,0 Z" Fill="Red"/> 
       </local:ColorComboBoxValue.Object> 
      </local:ColorComboBoxValue> 
      <local:ColorComboBoxValue Color="Blue"> 
       <local:ColorComboBoxValue.Object> 
        <Path Data="M0,0 L0,30 60,30 60,0 Z" Fill="Blue"/> 
       </local:ColorComboBoxValue.Object> 
      </local:ColorComboBoxValue> 
      <local:ColorComboBoxValue Color="Green"> 
       <local:ColorComboBoxValue.Object> 
        <System:String>Green</System:String> 
       </local:ColorComboBoxValue.Object> 
      </local:ColorComboBoxValue> 
     </local:ColorList> 
    </Window.Resources> 

    <ComboBox ItemsSource="{Binding Source={StaticResource ColorList}}" 
       SelectedItem="{Binding ActiveColor, ElementName=window}"> 
     <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <ContentPresenter Content="{Binding Path=Object}"/> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 
</Window> 
+0

是否有任何錯誤定義的on_select事件? – Arnej65 2010-05-14 16:51:46

+0

所有使用的代碼顯示在這裏,所以沒有定義任何事件... – 2010-05-18 09:17:07

回答

3

它真的很簡單。

Path是一個WPF對象,因此每個WPF對象只能有一個父對象。一旦WPF對象有一個父集,它就不能在另一個父集中使用。

這會發生什麼,DataTemplate會被加載,並顯示您的項目。您可以使用路徑選擇一個項目,並在組合框的Selected Item ContentPresenter中設置它(必須顯示)。這會從原始對象中分離路徑,導致您的項目「消失」。您的物品仍然存在,但由於路徑已從原始列表中分離,因此無法再看到它們,因爲它們不再具有可見對象。在字符串的情況下,它的工作原理是因爲字符串不是WPF對象。

希望這可以清理一些東西。

所以,現在的解決方案:

如果您想保留綠色的文字,你可以執行以下操作:

讓你的文字顏色枚舉ColorList:

public class ColorList : List<Color> { } 

丟掉一些東西:

public partial class Window1 : Window 
{ 
     public Window1() 
    { 
     this.Resources["ColorList"] = new[] { Color.Red, Color.Blue, Color.Green }; 
     InitializeComponent(); 
    } 

     private Color _activeColor; 
    public Color ActiveColor 
    { 
     get { return _activeColor; } 
     set 
     { 
      _activeColor = value; 
     } 
    } 
} 

public class ColorList : List<Color> { } 


public enum Color 
{ 
    Red, 
    Blue, 
    Green 
} 

並擴展您的DataTemplate設置一個speci對於紅色和藍色使用您的DataTemplate觸發對象FIC的DataTemplate:

<Window x:Class="WpfApplication6.Window1" 
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
xmlns:WpfApplication6="clr-namespace:WpfApplication6" 
Title="ComboBoxTest" Height="100" Width="200"> 


<ComboBox ItemsSource="{Binding Source={StaticResource ColorList}}" 
      SelectedItem="{Binding ActiveColor, ElementName=ComboBoxTest}"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <ContentControl Content="{Binding}" x:Name="content" /> 
      <DataTemplate.Triggers> 
       <DataTrigger Binding="{Binding}" Value="{x:Static WpfApplication6:Color.Red}"> 
        <Setter TargetName="content" Property="ContentTemplate"> 
         <Setter.Value> 
          <DataTemplate> 
           <Path Data="M0,0 L0,30 60,30 60,0 Z" Fill="Red"/> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
       <DataTrigger Binding="{Binding}" Value="{x:Static WpfApplication6:Color.Blue}"> 
        <Setter TargetName="content" Property="ContentTemplate"> 
         <Setter.Value> 
          <DataTemplate> 
           <Path Data="M0,0 L0,30 60,30 60,0 Z" Fill="Blue"/> 
          </DataTemplate> 
         </Setter.Value> 
        </Setter> 
       </DataTrigger> 
      </DataTemplate.Triggers> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 
</Window> 

清潔方法:

如果您希望讓所有的物品是一個顏色對象,您將需要一個轉換器要轉換的對象一個顏色枚舉值到顏色,你希望顯示:

<ComboBox ItemsSource="{Binding Source={StaticResource ColorList}}" 
      SelectedItem="{Binding ActiveColor, ElementName=ComboBoxTest}"> 
    <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <Path Data="M0,0 L0,30 60,30 60,0 Z" Fill="{Binding Converter={StaticResource ColorConverter}}"/> 
      </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

和一個漂亮的轉換器,它需要添加到資源:

public class ColorConverter : IValueConverter 
{ 
    #region IValueConverter Members 

    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     switch ((Color)value) 
     { 
      case Color.Red: 
       return Colors.Red; 
      case Color.Blue: 
       return Colors.Blue; 
      case Color.Green: 
       return Colors.Green; 
      default: 
       throw new ArgumentOutOfRangeException("value"); 
     } 
    } 

    public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) 
    { 
     throw new NotImplementedException(); 
    } 

    #endregion 
} 

更清潔;)希望這有助於..如果您有任何問題,我會在評論中回答他們!

+0

非常感謝您的回答,解決方案效果很好!綁定的部分獲取顏色對我來說不是必需的,因爲我的應用程序中的所有對象都是相同顏色的不同路徑。剛做了一個帶顏色的小示例應用程序,可以輕鬆展示我的問題。再次感謝:-) – 2010-05-18 11:46:22

+0

此外,由於資源創建爲一個數組我不需要創建一個新的類「公共類ColorList:列表 {}」 – 2010-05-18 11:57:00

+0

沒問題的隊友!很高興我能幫上忙! – Arcturus 2010-05-18 12:04:37