WPF Datagrid DataGridComboBoxColumn在运行时自动生成

时间:2011-07-09 21:43:10

标签: wpf vb.net .net-4.0

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

在其中一些自定义类中有几个列表。我可以获得正确自动生成的文本和复选框。当它遇到我的阵列时(我尝试了很多不同的类型)我只看到一个带有单词(Collection)的textboxcolumn。

例如 - 一个屏幕我正在获取有关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 个答案:

答案 0 :(得分: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