我的表单中有一个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。
答案 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();
}
}