2011-10-12 73 views
1

我有一個組合框,顯示可用系統顏色的列表。組合框中的每個項目都有一個預覽矩形和文本顏色名稱。在給定的時間內,我可能需要一次在屏幕上多達6個組合框。我創建了一個項目的靜態列表,以便在所有組合框中重用以減少開銷。它起作用,而且速度很快,但現在當我更改其他組合框屬性時,例如將字體粗細設置爲粗體時,它會影響所有組合框,而不僅僅是我將屬性應用到的組合框。使用ItemsSource綁定的組合框會影響其他屬性

這是我的代碼,全部在代碼後面完成。

我重用列表的宣言和組合框:

static private List<ListViewItem> _colorItems = null; 
    ComboBox _comboBoxColorList; 

然後在構造函數中我控制包含組合框我對初始創建列表的代碼:

 if (_colorItems == null) 
     { 
      _colorItems = new List<ListViewItem>(); 

      PropertyInfo[] colorProperties = typeof(Colors).GetProperties(BindingFlags.Static | BindingFlags.Public); 
      Dictionary<String, Color> colorDictionary = colorProperties.ToDictionary(p => p.Name, p => (Color)p.GetValue(null, null)); 
      ListViewItem newItem; 
      foreach (KeyValuePair<String, Color> keyPair in colorDictionary) 
      { 
       newItem = CreateListViewItem(keyPair.Key, keyPair.Value); 
       _colorItems.Add(newItem); 
      } 
     } 

然後,我創建的組合框:

 _comboBoxColorList = new ComboBox(); 
     _comboBoxColorList.Height = Constants.ListViewPropertyComboBoxHeight; 
     _comboBoxColorList.VerticalContentAlignment = VerticalAlignment.Center; 
     _comboBoxColorList.Background = Brushes.White; 
     _comboBoxColorList.ItemsSource = _colorItems; 
     _comboBoxColorList.SelectionChanged += new SelectionChangedEventHandler(comboBoxColorList_SelectionChanged); 
     Children.Add(_comboBoxColorList); 

再後來一個在事件處理程序我有這段代碼的組合框設置爲粗體:

  _comboBoxColorList.FontWeight = FontWeights.Bold; 

如果我讓這個_colorItems不是靜態萬物的行爲,因爲它應該的,但它是緩慢的。當_colorItems是靜態的時候速度非常快,但是上面的代碼行使所有的組合框共享item粗體。

任何洞察力或智慧都會很棒。

+0

標籤不屬於標題,離開它... –

+0

請將您的代碼發佈到您創建第二個組合框的位置。請張貼您如何附加事件處理程序和整個事件處理程序。 – Paparazzi

回答

1

而是直接創建ListBoxItems的,讓這個由框架來完成。事實上,您可以在XAML中完成代碼,而且應該在XAML中完成。

爲了使簡單:

與您創建一個新的類創建一個ObservableCollection,把它也許ColorInfo添加所有屬性,例如姓名,真實的色彩。並用你所有的顏色填充這個列表。 這可以重複使用,只要你想。

class ColorInfo 
{ 
    public Color Color{get;set;} 
    public string Name{get;set;} 
} 

ObservableCollection<ColorInfo> myColors; 

現在,您可以設置名單爲您ComboBoxItemsSource。最後你提供一個項目模板,每個項目應該是什麼樣子。

<ComboBox x:Name="_comboBoxColorList"> 
    <ComboBox.ItemTemplate> 
     <DataTemplate> 
      <DockPanel> 
      <Rectangle DockPanel.Dock="Left" Width="16" Height="16"> 
       <Rectangle.Fill> 
        <SolidColorBrush Color="{Binding Color}"/> 
       </Rectangle.Fill> 
      </Rectangle> 
       <TextBlock Fill="{Binding Name}"/> 
      </DockPanel> 
     </DataTemplate> 
    </ComboBox.ItemTemplate> 
</ComboBox> 

當然,你可以提取模板,並通過靜態資源引用它。

+0

我正在通過更新來嘗試您的方法。我擁有的軟件非常具有動態性,屏幕上顯示的內容基於通過配置文件讀入的內容。這就是爲什麼我通常總是在代碼背後做所有事情的原因,以及我沒有完全掌握WPF的事實。通過提取模板和參考是通過靜態資源來表達什麼意思?我沒有在創建此組合框的cs文件附帶的xaml文件。因此,我不知道在哪裏放置您定義的項目模板。我可以在App.xaml中定義它並引用它嗎?如果是的話那麼如何? – WPFNewbie

+0

當然,你可以做到這一點,其實這就是我的意思:)。只需將Datatemplate放在App.xaml中,給它一個像'x:Key =「colorComboBoxTemplate」'這樣的密鑰,然後就可以使用'System.Windows.Application.Current.FindResource(「colorComboBoxTemplate」)'查找它代碼,不要忘記將其轉換爲DataTemplate。實際上,你也說過「非常動態的軟件」,這就是WPF的強項。 ObservableCollection可以更新,並且所有顯示其內容的控件都會自動更新,而不需要任何額外的代碼。 – dowhilefor

+0

謝謝。所以我已經實施了,但沒有完全正常工作。我的列表包含所有顏色名稱,但顏色預覽部分未顯示。如果我將矩形中的填充更改爲硬編碼顏色,則會顯示該顏色,否則會將矩形留空。我將顏色和名稱這兩個屬性名稱都改爲其他名稱,以確保這不是問題,也沒有什麼區別。順便說一句,我沒有改變TextBlock使用Text屬性。 – WPFNewbie

0

如果那些ListViewItems是來自框架的,你不應該那樣做。如果你有一個在控件之間共享的列表,它應該只包含數據,而不是UI元素。如果您需要以某種方式顯示數據,請使用ItemTemplate和/或ItemContainerStyle

參見:Styling and Templating

(只需設置的ItemsSource不是的方式綁定...)

相關問題