C# 确定更改了哪些属性,并编辑所有选定项
我最近发现了如何在更改ListView中项目的属性时添加事件:C# 确定更改了哪些属性,并编辑所有选定项,c#,wpf,listview,inotifypropertychanged,C#,Wpf,Listview,Inotifypropertychanged,我最近发现了如何在更改ListView中项目的属性时添加事件: foreach (Profil item in gp.ListProfils) { if (item is INotifyPropertyChanged) { INotifyPropertyChanged observable = (INotifyPropertyChanged)item; observable.PropertyChanged += new Pr
foreach (Profil item in gp.ListProfils)
{
if (item is INotifyPropertyChanged)
{
INotifyPropertyChanged observable = (INotifyPropertyChanged)item;
observable.PropertyChanged +=
new PropertyChangedEventHandler(ItemPropertyChanged);
}
}
现在,我想将修改应用于所有选定的项目
我找到了如何识别已更改属性的名称:
private void ItemPropertyChanged(object sender, PropertyChangedEventArgs e)
{
if(sender is Profil)
{
string myPropertyName = e.PropertyName;
Profil editedProfile = (Profil)sender;
foreach(Profil prf in this.SelectedProfiles)
{
//prf.NAME_PROPERTY = editedProfile.NAME_PROPERTY
if (!this.ListProfilToEdit.Contains(editedProfile))
{
this.ListProfilToEdit.Add(editedProfile);
}
}
}
}
但是我如何替换注释中的行呢。
具体来说,如果我编辑了字段“宽度”,我想更改所有选定元素的宽度。
有没有一种方法可以做到这一点,而不需要创建一个单独的函数EditProperty(stringnameproperty)
有没有一种方法可以做到这一点,而不用创建一个单独的函数EditProperty(string nameProperty)
创建单独的方法与否取决于良好的设计和干净的代码,它不会以任何方式影响问题的核心。您始终可以创建单独的方法或在现有方法中编写代码
但是我如何替换注释中的行呢
现在还不清楚你在做什么,所以我怀疑你所问的问题是否可以用不同的方式解决,但事实上,你只是要求通过知道实例的名称来读写它们的属性。您将需要为此使用
为了执行后期绑定,访问在运行时创建的类型上的方法。参见主题
假设您的房产是公共的,这应该可以:
var propertyInfo = typeof(Profil).GetProperty(myPropertyName);
var value = propertyInfo.GetValue(editedProfile, null);
foreach(Profil prf in this.SelectedProfiles)
{
propertyInfo.SetValue(prf, value);
// ...other code.
}
也就是说,仔细使用反射,以便进一步阅读:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Linq.Expressions;
using System.Reflection;
namespace CoreAppMain
{
public class TypeAccessors<T> where T : class
{
//Getters
public static Dictionary<string, Func<T, object>> Getters = GetTypeGetters();
private static Dictionary<string, Func<T, object>> GetTypeGetters()
{
var _getters = new Dictionary<string, Func<T, object>>();
var props = typeof(T).GetProperties();
foreach (var p in props)
{
var entityParam = Expression.Parameter(typeof(T), "e");
Expression columnExpr = Expression.Property(entityParam, p);
Expression conversion = Expression.Convert(columnExpr, typeof(object));
var fct = Expression.Lambda<Func<T, object>>(conversion, entityParam).Compile();
_getters.Add(p.Name, fct);
}
return _getters;
}
//setters
public static Dictionary<string, Action<T, object>> Setters = GetTypeSetters();
public static Dictionary<string, Action<T, object>> GetTypeSetters()
{
var setters = new Dictionary<string, Action<T, object>>();
const BindingFlags flags = BindingFlags.Public | BindingFlags.Instance;
var propsToSet = typeof(T).GetProperties(flags)
.Where(x => x.CanWrite)
.ToList();
foreach (var field in propsToSet)
{
var propertyInfo = typeof(T).GetProperty(field.Name);
setters.Add(field.Name, GetPropertySetter<T>(propertyInfo));
}
return setters;
}
public static Action<TModel, object> GetPropertySetter<TModel>(PropertyInfo propertyInfo)
{
// Note that we are testing whether this is a value type
bool isValueType = propertyInfo.DeclaringType.IsValueType;
var method = propertyInfo.GetSetMethod(true);
var obj = Expression.Parameter(typeof(object), "o");
var value = Expression.Parameter(typeof(object));
// Note that we are using Expression.Unbox for value types
// and Expression.Convert for reference types
Expression<Action<TModel, object>> expr =
Expression.Lambda<Action<TModel, object>>(
Expression.Call(
isValueType ?
Expression.Unbox(obj, method.DeclaringType) :
Expression.Convert(obj, method.DeclaringType),
method,
Expression.Convert(value, method.GetParameters()[0].ParameterType)),
obj, value);
Action<TModel, object> action = expr.Compile();
return action;
}
}
}
使用系统;
使用System.Collections.Generic;
使用System.Linq;
使用System.Linq.Expressions;
运用系统反思;
名称空间CoreAppMain
{
公共类类型访问器,其中T:class
{
//吸气剂
公共静态字典Getters=GetTypeGetters();
私有静态字典GetTypeGetters()
{
var_getters=新字典();
var props=typeof(T).GetProperties();
foreach(道具中的var p)
{
var entityParam=表达式参数(typeof(T),“e”);
Expression columnExpr=Expression.Property(entityParam,p);
表达式转换=Expression.Convert(columnExpr,typeof(object));
var fct=Expression.Lambda(转换,entityParam.Compile();
_getters.Add(p.Name,fct);
}
返回获取者;
}
//二传手
公共静态字典Setters=GetTypeSetters();
公共静态字典GetTypeSetters()
{
var setters=newdictionary();
const BindingFlags flags=BindingFlags.Public | BindingFlags.Instance;
var propsToSet=typeof(T).GetProperties(标志)
.Where(x=>x.CanWrite)
.ToList();
foreach(propsToSet中的var字段)
{
var propertyInfo=typeof(T).GetProperty(field.Name);
Add(field.Name,GetPropertySetter(propertyInfo));
}
返回设置器;
}
公共静态操作GetPropertySetter(PropertyInfo PropertyInfo)
{
//请注意,我们正在测试这是否是值类型
bool isValueType=propertyInfo.DeclaringType.isValueType;
var method=propertyInfo.GetSetMethod(true);
var obj=表达式参数(typeof(object),“o”);
var值=表达式参数(typeof(object));
//请注意,我们对值类型使用Expression.Unbox
//和表达式。转换为引用类型
表达式表达式=
Lambda(
表情,打电话(
是ValueType吗?
表达式.Unbox(对象,方法.DeclaringType):
表达式.Convert(obj,方法.DeclaringType),
方法,,
Expression.Convert(值,方法.GetParameters()[0].ParameterType)),
obj,值);
Action Action=expr.Compile();
返回动作;
}
}
}
用法示例:
var cust1 = new Customer()
{
FirstName = "TOTOT",
LastName = "TITI"
};
var cust2 = new Customer()
{
FirstName = "XXXXXX",
LastName = "YYYYYY"
};
var value = TypeAccessors<Customer>.Getters[nameof(Customer.FirstName)](cust2);
TypeAccessors<Customer>.Setters[nameof(Customer.FirstName)](cust1, value);
Console.WriteLine(cust1.FirstName);
Console.ReadKey();
var cust1=新客户()
{
FirstName=“TOTOT”,
LastName=“TITI”
};
var cust2=新客户()
{
FirstName=“XXXXXX”,
LastName=“yyyyy”
};
var value=TypeAccessors.Getters[nameof(Customer.FirstName)](cust2);
打字机访问器.设置器[名称(客户.名字)](客户1,值);
Console.WriteLine(cust1.FirstName);
Console.ReadKey();
谢谢,事实上这正是我最后决定要做的事情(你写的那段代码)。因为我还注意到,我只需要对某些字段启用“多重编辑”,而不是对所有字段启用“多重编辑”,所以我做了一个函数,仅当字段名对应于这两个字段时才执行此操作。