更改动态组合框中组合框项目的文本样式

本文关键字:组合 文本 样式 项目 动态 | 更新日期: 2023-09-27 17:59:45

我的表单中有一个组合框,显示可用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; }
    }
}

现在,正如我在代码中所评论的,我希望组合框在bold中显示打开的端口。我不知道该怎么办。我在SO和谷歌上搜索了一段时间,但没有运气。如果有人简单地向我解释这一点,我将不胜感激。

更改动态组合框中组合框项目的文本样式

最简单的更改是

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

在WPF中,您可以通过覆盖显示模板来将更改应用于元素。

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

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

我在没有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();
    }
}