2016-08-02 96 views
0

我的窗體中顯示ComboBox,顯示可用COM端口的列表。這是我寫的代碼:更改動態組合框中ComboBox項目的文本樣式

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

現在的代碼,我在代碼中有評論,我想組合框顯示開闊港口黑體。我不知道該怎麼做。我在SO和google上搜索了一段時間,但沒有運氣。我很感激,如果有人簡單地向我解釋這一點 - WPF/C#noob。

+0

您可以設置某些屬性在ComboBoxItem模型,如ISOPEN,爲true。然後在xaml樣式中使用** [datatrigger](https://msdn.microsoft.com/en-us/library/system.windows.datatrigger(v = vs.110).aspx)**來更改外觀。 – 3615

+0

@ 3615作爲一個noob,我真的很感激答案。我一直在Google上搜索,現在我懇求一些東西來救我脫離所有的痛苦。 –

回答

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

美好而平穩。 –

+0

謝謝大家的積極反饋。當然,這是在沒有ViewModel的情況下完成的(它甚至可以在沒有DataContext的情況下工作,沒有Binding,但是直接將ComBoxItems直接添加到com_ports組合的Items屬性。下一步可以應用MVVM,如果需要,可以繼續使用更復雜的解決方案。 。現在再次感謝 – 2016-08-02 08:59:04

1

在WPF將更改應用於元素通過覆蓋有顯示模板。

一個很好的起點,以瞭解它是這個小教程在這裏: 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; } 

並使用此模板顯示該項目s:

<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(); 
    } 
} 
+0

非常感謝。這是一般的路線,但我個人更喜歡較短的解決方案。 –