我可以使用List <t>和List <expression>来填充wpf数据网格吗?

时间:2016-10-18 15:45:48

标签: c# wpf

我可以使用List<T>List<Expression>来填充wpf数据网格吗?

  {
      var processes = Process.GetProcesses().ToList();
      PopulateDataGrid( processes, x => x.ProcessName, x => GetSafeFilename( x ) );  
  }
  private string GetSafeFilename( Process p )
  {
     try
     {
        return p.MainModule.FileName;
     }
     catch ( Exception )
     {
        return "";
     }
  }

我的想法是,我希望能够传递一个list和params表达式列表来填充数据网格。我只想在datagrid上显示表达式列表。

我也希望能够获得所选行的基础对象。

我知道我可以使用匿名类型:

var list = processes.Select( x => new {TagObject = x, ProcessName = x.ProcessName, Filename = GetSafeFilename( x )} ).ToList();

但是我必须确保不将“TagObject”添加到datagrid。

有什么想法吗?我真的很喜欢语法的概念:

PopulateDataGrid( processes, x => x.ProcessName, x => GetSafeFilename( x ) ); 

但我不确定如何实现它。

1 个答案:

答案 0 :(得分:1)

您可以使用匿名类型并明确定义要在数据网格中查看的列:

<DataGrid AutoGenerateColumns="False" Name="dg">
    <DataGrid.Columns>
        <DataGridTextColumn Binding="{Binding ProcessName}" />
    </DataGrid.Columns>
</DataGrid>

如果TagObject在所有项目中都是唯一的,那么您可能需要考虑设置SelectedValuePath="TagObject"。然后,在代码中,您可以使用TagObject引用所选对象的SelectedValue属性:

var currentTagObject = dg.SelectedValue;

否则,您可以通过SelectedItem获取整个所选对象。

var selectedObject = dg.SelectedItem;

但是,如果要从所选对象中读取单个属性,因为它的类型是匿名类型,您可能必须使用反射。因此,我建议您为对象创建一个简单的数据类:

public class DataObject {
    public string TagObject {get;set;}
    public string ProcessName {get;set;}
    public string FileName {get;set;}
}

您可以在DataObject的构造函数中或在单独的函数中放置用于填充这些属性的逻辑。

然后你可以写下以下内容:

dg.ItemsSource = Process.GetProcesses().Select(x => new DataObject {
    TagObject = x,
    ProcessName = x.ProcessName,
    FileName = GetSafeFileName(x)
});