更改动态ComboBox中ComboBox项的文本样式

时间:2016-08-02 07:50:01

标签: c# wpf combobox

我的表单中有一个ComboBox,显示可用的COM端口列表。这是我写的代码:

[XAML]

<Window x:Class="test1.MainWindow" x:Name="cbtest1"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="200" Width="200">
    <Grid>
        <StackPanel Margin="40">
            <ComboBox x:Name="com_ports" ItemsSource="{Binding PortsList}"/>
        </StackPanel>
    </Grid>
</Window>

背后的代码

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Windows;
using System.Windows.Controls;

namespace test1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            var ports = new List<string>(System.IO.Ports.SerialPort.GetPortNames());
            var cb = new ObservableCollection<ComboBoxItem>();
            foreach (var x in ports)
            {
                cb.Add(new ComboBoxItem { Content = x });
                var p = new System.IO.Ports.SerialPort(x);
                if (p.IsOpen)
                {
                    // Bold that item in the combobox
                }
            }
            PortsList = cb;
            this.DataContext = this;
            InitializeComponent();
        }
        public ObservableCollection<ComboBoxItem> PortsList { get; set; }
    }
}

现在,正如我在代码中评论的那样,我希望ComboBox以粗体显示开放端口。我不知道该怎么做。我在搜索引擎优化和谷歌搜索了一段时间,但没有运气。我很感激,如果有人向我解释这个 - 一个WPF / C#noob。

2 个答案:

答案 0 :(得分:3)

最简单的改变是

        foreach (var x in ports)
        {
            var addMe = new ComboBoxItem { Content = x };
            cb.Add(addMe);
            var p = new System.IO.Ports.SerialPort(x);
            if (p.IsOpen)
            {
                addMe.FontWeight = FontWeights.Bold;
            }
        }

答案 1 :(得分:1)

在WPF中,您可以通过覆盖display-template来对元素应用更改。

理解它的一个很好的起点是这里的小教程: link

请注意,这种方法看起来有点复杂,但它也非常灵活,您可以使用此方法做其他各种事情。

我在没有Visual Studio的情况下写这个,所以可能会有一些语法错误

对于您的具体示例,我将使用以下模型类,以便您可以更轻松地绑定到某些属性:

public class MyPortModel : INotifyPropertyChanged
{
    private string _displayName;
    private bool _isOpen;

    public string DisplayName
    {
        get { return _displayName; }
        set
        {
            _displayName = value;
            OnPropertyChanged("DisplayName");
        }
    }

    public bool IsOpen
    {
        get { return _isOpen; }
        set
        {
            _isOpen = value;
            OnPropertyChanged("IsOpen");
        }
    }

    public event PropertyChangedEventHandler PropertyChanged;

    protected virtual void OnPropertyChanged([CallerMemberName] string propertyName = null)
    {
        PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
    }
}

然后将您的代码更改为以下内容:

public MainWindow()
{
    var ports = new List<string>(System.IO.Ports.SerialPort.GetPortNames());
    var cb = new ObservableCollection<MyPortModel>();
    foreach (var x in ports)
    {
        var p = new System.IO.Ports.SerialPort(x);
        cb.Add(new MyPortModel { DisplayName = x,IsOpen = p.IsOpen});
    }
    PortsList = cb;
    this.DataContext = this;
    InitializeComponent();
}
public ObservableCollection<MyPortModel> PortsList { get; set; }

并使用此模板显示项目:

<ComboBox x:Name="com_ports"
            ItemsSource="{Binding PortsList}">
    <ComboBox.Resources>
        <local:IsOpenBoldConverter x:Key="IsOpenConverter"/>
    </ComboBox.Resources>
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBlock Text="{Binding Path=DisplayName, UpdateSourceTrigger=PropertyChanged}"
                        FontWeight="{Binding Path=IsOpen, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource IsOpenConverter}}"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

如您所见,转换器用于确定项目是否应显示为粗体或正常。 下面是转换器的代码:

public class IsOpenBoldConverter:IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is bool)
        {
            return ((bool) value) ? FontWeights.Bold : FontWeights.Normal;
        }
        return FontWeights.Normal;
    }

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