2011-07-09 38 views
1

私はvb.net 4.0 wpfプロジェクトにデータグリッドを持っています。私はDataGridComboBoxColumnをバインドする方法についてXAMLの多くの例を見てきましたが、私は列を自動生成するので、コードでこれを行う必要があります。私は、datagridbindingソースを複数のデータセットに切り替えます。WPF Datagrid DataGridComboBoxColumn実行時に自動生成

これらのカスタムクラスの中には、いくつかのリストがあります。テキストとチェックボックスを自動的に生成するようにすることができます。私の配列(私はさまざまな種類を試してみました)に遭遇すると、その中に単語(Collection)を持つtextboxcolumnが表示されます。

たとえば、 - 1画面私はWMI呼び出しに関するシステム情報を取得しています。 1つの呼び出しでサーバー上のすべてのIPアドレスが返されます(最大8つのIPアドレスを持つことができます)。IPアドレスごとに列を必要としません。私はそれらをドロップダウンして見ることができるように、それらのリストをデータグリッドに含めたいと思います。

これが可能かどうか、あるいは私が何か間違っているのであれば、どんな提案もありますか?

サンプルコード

Imports System.Collections.ObjectModel 

Class MainWindow 

Dim ServerInfoArray As ObservableCollection(Of ServerInfo) = New ObservableCollection(Of ServerInfo) 

Private ReadOnly _ipAddresses As ObservableCollection(Of String) = New ObservableCollection(Of String) 


Private Sub GetInfo(ByVal list As List(Of String)) 
    For Each server As String In list 

     Dim tempip As List(Of String) = New List(Of String) 
     Dim sinfo As ServerInfo = New ServerInfo 

     tempip.Add("192.129.123.23") 
     tempip.Add("23.213.223.21") 

     sinfo.IPArray = tempip 
     sinfo.Servername = server 

     ServerInfoArray.Add(sinfo) 

    Next 
End Sub 

Private Sub Button1_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles Button1.Click 

    Dim serverlist As List(Of String) = New List(Of String) 
    serverlist.Add("Test") 
    serverlist.Add("Random") 
    serverlist.Add("Local") 
    GetInfo(serverlist) 

End Sub 

Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded 
    Dim Col_Serial As DataGridTextColumn = New DataGridTextColumn() 
    Col_Serial.Binding = New Binding("Servername") 
    Col_Serial.Header = "Servername" 
    Col_Serial.Width = 40 

    Dim Col_IPArray = New DataGridComboBoxColumn() 
    Col_IPArray.Header = "IP Addresses" 
    Col_IPArray.IsReadOnly = True 
    Col_IPArray.ItemsSource = Me._ipAddresses 
    Col_IPArray.SelectedItemBinding = New Binding("IPArray") 

    DataGrid1.Columns.Add(Col_Serial) 
    DataGrid1.Columns.Add(Col_IPArray) 
    DataGrid1.ItemsSource = ServerInfoArray 
End Sub 
End Class 

Class ServerInfo 

Dim _Servername As String 
Dim _IPArray As List(Of String) 

Public Property Servername() As String 
    Get 
     Return _Servername 
    End Get 
    Set(ByVal value As String) 
     _Servername = value 
    End Set 
End Property 

Public Property IPArray As List(Of String) 
    Get 
     Return _IPArray 
    End Get 
    Set(ByVal value As List(Of String)) 
     _IPArray = value 
    End Set 
End Property 

Public Sub New() 
    _Servername = Nothing 
    _IPArray = New List(Of String) 
End Sub 

エンドクラス

答えて

1

ない私は完全に理解していますが、あなたはAutoGenerateColumnsと一緒に暮らすことができる場合= Falseを、あなたが列を操作できるかどうかわから、そのプロパティをありがとうおよび以下のようなコードからのバインディングです。したがって、コードから列をセットアップするために必要なロジックを使用することができます。 DataGridのアイテムとは別のオブジェクトからコンボボックスの列アイテムをどのようにソースできるかを示してみました。

これはコードビハインドですべてを行いましたが、MVVMの観点からは、好みのアプローチによりますが、スピンするコントローラクラスから同じロジックを達成できる可能性がありますあなたのビューモデルなどをアップしてください...

希望します!

XAML ...

<Window x:Class="MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    Title="MainWindow" Height="350" Width="525"> 
    <StackPanel> 
     <Button x:Name="btnRefreshIPList">Refresh list of IPs</Button> 
     <DataGrid x:Name="dataGrid1"></DataGrid> 
    </StackPanel> 
</Window> 

の背後にあるコード

Imports System.Collections.ObjectModel 

Class MainWindow 

    'The list of IPs for column's ItemSource property 
    Private ReadOnly _ipAddresses As ObservableCollection(Of String) 

    'The items for binding to the DataGrid's ItemsSource 
    Private _items As List(Of MyObjectWithIPAddress) 

    Public Sub New() 

     ' This call is required by the designer. 
     InitializeComponent() 

     ' Add any initialization after the InitializeComponent() call. 
     _ipAddresses = New ObservableCollection(Of String) 
     _items = New List(Of MyObjectWithIPAddress) 

    End Sub 

    Private Sub Window_Loaded(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles MyBase.Loaded 

     Me.dataGrid1.AutoGenerateColumns = False 

     dataGrid1.Columns.Clear() 

     'Example of text column (Text bound to Name property) 
     Dim dgTxtCol = New DataGridTextColumn() 
     dgTxtCol.Header = "Name" 
     dgTxtCol.Binding = New Binding("Name") 
     dataGrid1.Columns.Add(dgTxtCol) 

     'Example of combobox column (SelectedItem bound to IPAddress) 
     Dim dgCmbCol = New DataGridComboBoxColumn() 
     dgCmbCol.Header = "IP Address" 
     dgCmbCol.ItemsSource = Me._ipAddresses 
     dgCmbCol.SelectedItemBinding = New Binding("IPAddress") 
     dataGrid1.Columns.Add(dgCmbCol) 

     'Add items to DataGrid 
     _items.Add(New MyObjectWithIPAddress("foo1")) 
     _items.Add(New MyObjectWithIPAddress("foo2")) 

     Me.dataGrid1.ItemsSource = Me._items 

    End Sub 

    ''' <summary> 
    ''' To emulate fetching the object that has the IP list 
    ''' </summary> 
    ''' <returns></returns> 
    ''' <remarks></remarks> 
    Private Function GetIpList() As MyObjectWithListOfIPs 
     Dim inst = New MyObjectWithListOfIPs 
     inst.IPList = New List(Of String)(New String() {"10.0.0.1", "10.0.0.2", "10.0.0.3"}) 
     Return inst 
    End Function 

    ''' <summary> 
    ''' Updates the ObservableCollection instance based on business object 
    ''' </summary> 
    ''' <remarks></remarks> 
    Private Sub RefreshIpAddresses() 
     _ipAddresses.Clear() 
     For Each ip As String In GetIpList().IPList 
      _ipAddresses.Add(ip) 
     Next 
    End Sub 

    Private Sub btnRefreshIPList_Click(sender As System.Object, e As System.Windows.RoutedEventArgs) Handles btnRefreshIPList.Click 
     RefreshIpAddresses() 
    End Sub 
End Class 

''' <summary> 
''' Object with response data (e.g., list of IPs) 
''' </summary> 
''' <remarks></remarks> 
Class MyObjectWithListOfIPs 

    Private _ipList As List(Of String) 
    Public Property IPList() As List(Of String) 
     Get 
      Return _ipList 
     End Get 
     Set(ByVal value As List(Of String)) 
      _ipList = value 
     End Set 
    End Property 

End Class 

''' <summary> 
''' Disperate object that "has an" address 
''' </summary> 
''' <remarks></remarks> 
Class MyObjectWithIPAddress 

    Public Sub New(name As String) 
     Me._name = name 
    End Sub 

    Private _name As String 
    Public Property Name() As String 
     Get 
      Return _name 
     End Get 
     Set(ByVal value As String) 
      _name = value 
     End Set 
    End Property 

    Private _ipAddress As String 
    Public Property IPAddress() As String 
     Get 
      Return _ipAddress 
     End Get 
     Set(ByVal value As String) 
      _ipAddress = value 
     End Set 
    End Property 

End Class 
+0

はあなたにblinsありがとう...、私はそこに自動生成は、ArrayListのを使用するための簡単な方法があったか、または期待していましたリスト(文字列の)は簡単にコンボボックスを作る。しかし、私はタブの変更イベント中に私が欲しい私の列をクリアして再作成するのは難しくないと思います。 datagridcomboboxcolumnを適切にバインドするコードをありがとう。私は明日それを試してみる。 – Jasin

+0

少し助けが必要な場合があります。コンボボックスはローカル配列にバインドされています。私のデータグリッドは、必要なすべての変数を持つクラスである配列にバインドされています。私のクラスは15の異なる文字列を含むServerInfoであり、1つはIP ArrayというこのList(Of String)です。データグリッドは私のServerInfoArray = List(Of ServerInfo)にバインドされています。 – Jasin

+1

私の例では(ObservableCollectionにリストアイテム(pocoオブジェクトから)をロードしています。 ObservableCollectionは、アイテムが追加、削除されたときにコレクションが通知を変更してバインディングを更新する特別なタイプの汎用コレクションです。プレーンなリストはこれを行いませんので、ビューをリストにバインドすると、リスト内の項目を変更するだけでコンボボックスの項目は変更されません(ObservableCollectionを使用すると、それらの項目が変更されます)。 – blins

関連する問題