【问题标题】:ComboBox using ItemsSource binding affects other properties使用 ItemsSource 绑定的 ComboBox 会影响其他属性
【发布时间】:2011-12-06 02:29:31
【问题描述】:

我有一个显示可用系统颜色列表的组合框。组合框中的每个项目都有一个预览矩形和文本颜色名称。在给定的时间,我可能一次需要在屏幕上显示多达 6 个这样的组合框。我创建了一个静态项目列表,以便在所有组合框中重复使用以减少开销。它可以工作,而且速度很快,但现在当我更改其他组合框属性(例如将字体粗细设置为粗体)时,它会影响所有组合框,而不仅仅是我应用该属性的组合框。

这是我的代码,全部在后面的代码中完成。

我重用的列表和组合框的声明:

    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 为静态时,它非常快,但上面的行使所有组合框都共享项目源粗体。

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

【问题讨论】:

  • 标签不属于标题,留下它...
  • 请在您创建第二个组合框的位置发布代码。请发布您如何附加事件处理程序和整个事件处理程序。

标签: wpf binding combobox properties


【解决方案1】:

不要直接创建ListBoxItems,而是让框架来完成。事实上,您在代码中做了很多可以而且应该在 XAML 中完成的工作。

为了简单起见:

使用您创建的新类创建一个ObservableCollection,可以将其命名为ColorInfo,添加您的所有属性,例如名称、真实颜色。并用你所有的颜色填写这个列表。 这可以根据需要多次重复使用。

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

ObservableCollection<ColorInfo> myColors;

现在,您将此列表设置为您的ComboBox 的ItemsSource。最后你提供一个项目模板,每个条目应该是什么样子。

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

当然,您可以提取模板并通过 StaticResource 引用它。

【讨论】:

  • 我正在通过更新来尝试您的方法。我拥有的软件非常动态,屏幕上显示的内容是基于通过配置文件读入的内容。这就是为什么我通常总是在代码后面做所有事情,以及我对 WPF 还没有扎实的掌握。提取模板和引用是通过静态资源是什么意思?我在创建此组合框的 cs 文件中没有附带 xaml 文件。因此,我不知道将您定义的项目模板放在哪里。我可以在 App.xaml 中定义它并引用它吗?如果是,那怎么办?
  • 当然可以,事实上我就是这个意思:)。只需将 Datatemplate 放在您的 App.xaml 中,给它一个像 x:Key="colorComboBoxTemplate" 这样的键,然后您可以使用 System.Windows.Application.Current.FindResource("colorComboBoxTemplate") 在代码中查找它,不要忘记将其转换为 DataTemplate。实际上,您还说“非常动态的软件”,这就是 WPF 的强项。 ObservableCollection 可以更新,所有显示其内容的控件都会自动更新,无需任何额外代码。
  • 谢谢。所以我已经实现了它,但它没有完全工作。我的列表包含所有颜色名称,但颜色预览部分未显示。如果我将矩形中的填充更改为硬编码颜色,它将显示该颜色,否则将矩形留空。我将颜色和名称的属性名称都更改为其他名称,以确保这不是问题并且没有任何区别。顺便说一句,我确实将 TextBlock 更改为使用 Text 属性。
  • 另一个观察结果,我第一次打开一个特定的组合框时它会犹豫,有延迟,但在随后的打开时它很快。
  • 我已经确认,当我应用粗体等属性时,这确实可以解决问题。所以,我只需要显示颜色以及如何进行编程默认选择?
【解决方案2】:

如果那些ListViewItems 是来自框架的那些,你不应该这样做。如果您有一个在控件之间共享的列表,它应该只包含数据,而不是 UI 元素。如果您需要以某种方式显示数据,请使用ItemTemplate 和/或ItemContainerStyle。

另请参阅:Styling and Templating

(顺便设置ItemsSource并不是绑定...)

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2015-04-07
    • 1970-01-01
    • 1970-01-01
    • 2018-08-27
    • 2012-01-08
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多