c# - WPF 使用 XAML 将 List<KeyValuePair<,>> 绑定(bind)到 DataGrid

标签 c# wpf xaml data-binding datagrid

我想通过 DataGrid 显示我的计算机的所有网络接口(interface),并且我有以下类(即 .xaml.cs Controller ):

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 而无法解析

有人可以告诉我我做错了什么吗,正如你所看到的,我真的不明白数据绑定(bind)是如何工作的^^。

最佳答案

您的bindingListPrintStatus()中的局部变量。在该方法之外它是不可见的。您需要将这些项目放在 View 可以到达的地方。

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 中,您需要绑定(bind)到 BindingList(我已更改大小写以匹配标准 .NET 实践)作为窗口的属性。它应该是您的 View 模型的成员。在这种情况下,您将绑定(bind)到 {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 绑定(bind)非常易于使用。如果您开始养成这种习惯,您将打破用户控件属性的绑定(bind)。它总是会造成困惑。

关于c# - WPF 使用 XAML 将 List<KeyValuePair<,>> 绑定(bind)到 DataGrid,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43458028/

相关文章:

c# - Visual Studio 2017 Xamarin 中缺少表单 Xaml 页面

c# - 设置数据绑定(bind) DropDownList 的 SelectedValue

c# - 从父窗体打开文件到子窗体的文本框 C#

c# - 在 C# 中从客户端向服务器发送字符串

c# - WinForm 滚动查看器

WPF:使用 DataGridComboBoxColumn 进行数据绑定(bind)

wpf - 如何在透明矩形上绘制阴影?

c# - 如何为 WCF 配置 log4net

c# - DataGridHyperlinkColumn 突出显示时的文本颜色

c# - WPF 与 RelativeSource 和 AncestorType 的绑定(bind)