C# 我可以使用列表吗<;T>;和一份清单<;表达式>;要填充wpf数据网格?
我可以使用C# 我可以使用列表吗<;T>;和一份清单<;表达式>;要填充wpf数据网格?,c#,wpf,C#,Wpf,我可以使用列表和列表来填充wpf数据网格吗 { var processes = Process.GetProcesses().ToList(); PopulateDataGrid( processes, x => x.ProcessName, x => GetSafeFilename( x ) ); } private string GetSafeFilename( Process p ) { try {
列表
和列表
来填充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 "";
}
}
其思想是,我希望能够传递一个表达式列表和参数列表来填充datagrid。我只想显示datagrid上的表达式列表
我还希望能够获得所选行的基础对象
我知道我可以使用匿名类型,如:
var list = processes.Select( x => new {TagObject = x, ProcessName = x.ProcessName, Filename = GetSafeFilename( x )} ).ToList();
但是,我必须确保不要将“TagObject”添加到数据网格中
有什么想法吗?我真的很喜欢语法的想法:
PopulateDataGrid( processes, x => x.ProcessName, x => GetSafeFilename( x ) );
但是我不知道如何实现它。您希望提供一组表达式,并使用每个表达式在网格中创建自己的列。您必须解决一个主要问题:使用对象的属性的数据绑定来解决DataGrid列:
<DataGridTextColumn Header="ProcessName" Binding="{Binding ProcessName}" />
PopulateDataGrid(processes, x => new { x.ProcessName, Path = x.MainModule.FileName });
public static void PopulateDataGrid<TElement, TFieldsExpression>(this DataGrid dg, IEnumerable<TElement> itemsSource, Expression<Func<TElement, TFieldsExpression>> fieldsExpr) {
}
然后您可以编写以下方法:
public static void PopulateDataGrid<TElement, TFieldsExpression>(this DataGrid dg, IEnumerable<TElement> itemsSource, Expression<Func<TElement, TFieldsExpression>> fieldsExpr) {
dg.ItemsSource = itemsSource;
dg.Columns.Clear();
var fields = ParseFields(fieldsExpr);
foreach (var (name, expr) in fields) {
if (expr is MemberAccessExpression mexpr) {
dg.Columns.Add(new DataGridTextColumn {
Header = name,
Binding = new Binding(mexpr.Member.Name)
})
} else {
throw new ArgumentException("Unhandled expression type.");
}
}
}
注:大部分来自于伴随着一个。示例代码处理其他表达式类型、长路径链(例如x.MainModule.FileName
)和对String.Format
的方法调用
助手扩展:
// using System.Reflection;
public static bool IsAnonymous(this Type type) =>
type.HasAttribute<CompilerGeneratedAttribute>() && type.Name.Contains("Anonymous") && type.Name.ContainsAny("<>", "VB$");
public static bool HasAttribute<TAttribute>(this MemberInfo mi, bool inherit = false) where TAttribute : Attribute =>
mi.GetCustomAttributes(typeof(TAttribute), inherit).Any();
public static bool ContainsAny(this string s, params string[] testStrings) =>
testStrings.Any(x => s.Contains(x));
//使用System.Reflection;
公共静态布尔值不合法(此类型)=>
type.HasAttribute()&&type.Name.Contains(“匿名”)&&type.Name.ContainsAny(“,”VB$”);
公共静态bool HasAttribute(此MemberInfo mi,bool inherit=false),其中tatAttribute:Attribute=>
GetCustomAttributes(typeof(tatAttribute),inherit).Any();
公共静态bool ContainsAny(此字符串s,参数字符串[]testStrings)=>
任何(x=>s.Contains(x));
当你谈到表达式时,你的意思是,对吗?因为WPF有自己的类。我重写了我对这个问题的答案。我不确定我写原始答案时的想法。
private static List<(string name, Expression expr)> ParseFields<TElement, TFieldsExpression>(Expression<Func<TElement, TFieldsExpression>> fieldsExpression) {
var body = fieldsExpression.Body;
switch (body) {
// an array initialization with elements
// (as opposed to an array initialization with bounds -- new int[5])
case NewArrayExpression newArrayExpr when body.NodeType == ExpressionType.NewArrayInit:
return newArrayExpr.Expressions.Select(x => ("", x)).ToList();
// anonymous type
// the IsAnonymous extension method is included at the end of the post
case NewExpression newExpr when newExpr.Type.IsAnonymous():
return newExpr.Constructor.GetParameters().Select(x => x.Name).Zip(newExpr.Arguments).ToList();
default:
throw new ArgumentException("Unhandled expression type.");
}
}
public static void PopulateDataGrid<TElement, TFieldsExpression>(this DataGrid dg, IEnumerable<TElement> itemsSource, Expression<Func<TElement, TFieldsExpression>> fieldsExpr) {
dg.ItemsSource = itemsSource;
dg.Columns.Clear();
var fields = ParseFields(fieldsExpr);
foreach (var (name, expr) in fields) {
if (expr is MemberAccessExpression mexpr) {
dg.Columns.Add(new DataGridTextColumn {
Header = name,
Binding = new Binding(mexpr.Member.Name)
})
} else {
throw new ArgumentException("Unhandled expression type.");
}
}
}
dg.PopulateDataGrid(list, x => new [] {x.ProcessName, x.HasExited, x.MachineName};
// using System.Reflection;
public static bool IsAnonymous(this Type type) =>
type.HasAttribute<CompilerGeneratedAttribute>() && type.Name.Contains("Anonymous") && type.Name.ContainsAny("<>", "VB$");
public static bool HasAttribute<TAttribute>(this MemberInfo mi, bool inherit = false) where TAttribute : Attribute =>
mi.GetCustomAttributes(typeof(TAttribute), inherit).Any();
public static bool ContainsAny(this string s, params string[] testStrings) =>
testStrings.Any(x => s.Contains(x));