2017-04-17 68 views
1

我想显示经由数据网格我的计算机的所有NetworkInterfaces和我有下面的类(也就是.xaml.cs控制器)结合列表 >到数据网格: WPF使用XAML

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

使用属性公共的ObservableCollection <字典<串,对象>>的BindingList {得到;组; }并在PrintStatus()方法内为此属性添加值。 – user2526236

回答

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绑定非常容易使用。如果你开始养成它的习惯,你会打破你的用户控件的属性绑定。它总是造成混乱。

+0

谢谢你现在几乎可以工作,但在将代码更改为你提供的内容后发生了一件奇怪的事情:密钥和值列以及它们的内容是双重的,例如'Key |值| Key |价值' –

+1

@MartinNiederl哎呀,请参阅更新:我向'DataGrid'添加了'AutoGenerateColumns ='False''。您可以通过将其忽略(该属性的默认值为True)并省略DataGrid.Columns来获得相同的效果 - 稍后我将添加该更新。 –

+0

@MartinNiederl查看新更新 –