2011-07-09 36 views
1

我在我的vb.net 4.0 wpf项目中有一个datagrid。我已经在XAML中看到了很多关于如何绑定DataGridComboBoxColumn的示例,但是我需要在代码中执行此操作,因为我有自动生成的列。我将datagridbinding源切换到多个数据集。WPF Datagrid DataGridComboBoxColumn在运行时自动生成

这些自定义类中的一些是几个列表。我可以让文本和复选框自动生成正确。当它遇到我的数组时(我尝试了很多不同的类型),我只看到一个文本框列表(集合)在其中。

例如 - 一个屏幕我抓住WMI调用的系统信息。其中一个调用会返回服务器上的所有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生活=假,那么你可以操纵的列,它们的属性并从下面的代码绑定。所以你可以使用你需要的任何逻辑来设置代码中的列。我试图展示如何从不同于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

我可能需要一点帮助,你的组合框绑定到本地数组。我的datagrid绑定到一个数组,这是一个包含所有我需要的变量的类。我的类是ServerInfo,它包含15个不同的字符串,一个是名为IP Array的List(Of String)。 Datagrid绑定到我的ServerInfoArray = List(的ServerInfo) – Jasin

+1

请注意在我的示例中(因为它过于简化)我将列表项(从poco对象)加载到ObservableCollection中。 ObservableCollection是一种特殊类型的泛型集合,它在添加,删除项目时触发集合更改通知,从而导致绑定被更新。一个普通的List不会这样做,所以如果你将你的视图绑定到一个列表上,那么通过简单地改变列表中的项目(如果你使用ObservableCollection,他们将会),组合框项目不会改变。 – blins

相关问题