I have a combo box that displays a list of available system colors. Each item in the combo box has a preview rectangle and the text color name. At a given time I may need as many as 6 of these combo boxes on the screen at once. I created a static list of items to reuse across all combo boxes to reduce overhead. It works, and it is fast, but now when I change other combo box properties such as setting the font weight to bold, it affects all combo boxes, not just the one I applied the property to.
Here is my 开发者_JAVA百科code, all done in code behind.
Declaration of the list I reuse and the combo box:
static private List<ListViewItem> _colorItems = null;
ComboBox _comboBoxColorList;
Then in the constructor for my control that contains the combo box I have the code for the initial creation of the list:
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);
}
}
Then I create the combo box:
_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);
Then later one in an event handler I have this code to set the combo box to bold:
_comboBoxColorList.FontWeight = FontWeights.Bold;
If I make it so that _colorItems is not static everythings behaves as it should, but it is slow. When _colorItems is static it is very fast, but the line above makes all combo boxes taht share the item source bold.
Any insight or wisdom would be great.
Instead of creating ListBoxItems
directly, let this be done by the Framework. In fact you do alot in code which can, and should, be done in XAML.
To make it simple:
Create an ObservableCollection
with a new class you create, call it maybe ColorInfo
add all your properties like name, the real color. And fill this list with all your colors.
This can be reused as often as you want.
class ColorInfo
{
public Color Color{get;set;}
public string Name{get;set;}
}
ObservableCollection<ColorInfo> myColors;
Now, you set this List as the ItemsSource
of your ComboBox
. And finally you provide an item template, how each entry should look like.
<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>
Of course you could extract the Template and reference it via StaticResource.
If those ListViewItems
are the ones from the framework you should not do that. If you have a list that is shared between controls it should only contain data, not UI-elements. If you need the data to be displayed in a certain way use the ItemTemplate
and/or the ItemContainerStyle
.
See also: Styling and Templating
(Just setting the ItemsSource is not a binding by the way...)
精彩评论