WPF绑定列表<keyvaluepair <,>&gt;使用XAML到DataGrid

时间:2017-04-17 19:17:28

标签: c# wpf xaml data-binding datagrid

我想通过DataGrid显示我的计算机的所有NetworkInterfaces,我有以下类(即.xaml.cs控制器):

public partial class Network : Window
{
    public Network()
    {
        PrintStatus();
        InitializeComponent();
    }

    public void PrintStatus()
    {
        var bindingList = new List<KeyValuePair<string, object>>();

        foreach (NetworkInterface card in networkCards)
        {
            foreach (PropertyInfo prop in typeof(NetworkInterface).GetProperties())
                bindingList.Add(new KeyValuePair<string, object>(prop.Name, prop.GetValue(card, null)));
        }
    }
}

我尝试过跟随,但这不起作用:

<DataGrid x:Name="NetInfo" ItemsSource="{Binding Source=bindingList}">
    <DataGrid.Columns>    
        <DataGridTextColumn Header="Key" Binding="{Binding Key}"/>
        <DataGridTextColumn Header="Value" Binding="{Binding Value}"/>    
    </DataGrid.Columns>
</DataGrid>

在VisualStudio中,当我将鼠标移动到Binding标记中的键或值时,我会收到 由于未知DataContext 而无法解析的消息。

有人可以告诉我我做错了什么,因为你可以看到我真的不明白数据绑定是如何工作的。^ /。

1 个答案:

答案 0 :(得分:1)

您的bindingListPrintStatus()中的本地变量。它在该方法之外是不可见的。您需要将项目放在视图可以到达的位置。

public Network()
{
    InitializeComponent();

    BindingList = new ObservableCollection<KeyValuePair<string, object>>();

    PrintStatus();
}


public ObservableCollection<KeyValuePair<string, object>> BindingList { get; private set; }

public void PrintStatus()
{
    BindingList.Clear();

    foreach (NetworkInterface card in networkCards)
    {
        foreach (PropertyInfo prop in typeof(NetworkInterface).GetProperties()) 
        {
            BindingList.Add(new KeyValuePair<string, object>(prop.Name, prop.GetValue(card, null)));
        }
    }
}

在XAML中,您需要绑定到BindingList(我已将大小写更改为与标准.NET实践相匹配)作为窗口的属性。它应该是您的viewmodel的成员。在这种情况下,您将绑定到{Binding BindingList}。但是你没有,所以这是行不通的。

默认情况下,DataGrid会自动为您提供的集合中的每个属性生成一列。由于您定义了自己的列,因此默认情况下它会将您的列添加到这些列中。您可以通过设置AutoGenerateColumns="False"来关闭它,如下所示。

<DataGrid 
    x:Name="NetInfo" 
    AutoGenerateColumns="False"
    ItemsSource="{Binding BindingList, RelativeSource={RelativeSource AncestorType=Window}}"
    >
    <DataGrid.Columns>    
        <DataGridTextColumn Header="Key" Binding="{Binding Key}"/>
        <DataGridTextColumn Header="Value" Binding="{Binding Value}"/>    
    </DataGrid.Columns>
</DataGrid>

您也可以让它继续并自动生成列,并且不要定义自己的列。如果您想定义自己的标题,或更改格式,甚至省略您不关心的一列或两列,您的原始方法可以提供更大的灵活性。只是覆盖所有的基础。

<DataGrid 
    x:Name="NetInfo" 
    ItemsSource="{Binding BindingList, RelativeSource={RelativeSource AncestorType=Window}}"
    />

DataContext = this;是不好的做法。在一个窗口中,它相对无害,但正如您在上面所看到的,它永远不必要。 RelativeSource绑定非常容易使用。如果你开始习惯它,你将打破对用户控件属性的绑定。它总是会造成混乱。