2016-08-02 10 views
0

使用可能なCOMポートのリストを表示するフォームにComboBoxがあります。動的コンボボックスの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

あなたがtrueに、のIsOpenのように、ComboBoxItemモデルにいくつかのプロパティを設定することができます。そして、外観を変更するには、xamlスタイルで** [datatrigger](https://msdn.microsoft.com/en-us/library/system.windows.datatrigger(v = vs.110).aspx)**を使用します。 – 3615

+0

@ 3615 noobとして、私は本当に答えを感謝します。私はしばらくの間、グーグルグーグルをしていましたが、今私はすべての苦しみから私を救うために何かを頼みます。 –

答えて

3

一番簡単なのは、あなたがそこに表示テンプレートをオーバーライドすることによって要素に変更を適用するWPFでは

 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なしでもバインディングなしでも動作できますが、ComBoxItemをcom_portsコンボアイテムプロパティに直接追加するだけです)。次のステップは、MVVMを適用してより複雑な解決策をとることができます。 。ありがとうございます。 –

1

だろう。それを理解するために

良い始点がここにこの小さなチュートリアルです: 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> 

このように、コンバータを使用すると、項目を太字または標準で表示するかどうかを判断できるようになります。コンバータの をHERESコード:

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

ありがとうございます。これは一般的な方法ですが、個人的には、私はより短いソリューションを好む。 –

関連する問題