有个 C#相关问题咨询下各位大佬: 比如我有个这样的类 class person() {
public int Age{get;set;}
public string Name{get;set;}
public void Run();
public void SaySomeThing(string words);
public otherObject Others{get; private set;} //这个对象里面还有属性或方法
}
我现在想实现功能就是我在用户界面上对这个类的属性进行访问赋值,例如这样 我创建了一个小红的 person,界面上我选择了小红后,那么可选的属性 AGE 经过翻译后显示为[年龄],后面有个数字框 用户可以输入 50,选择 name 属性,经过翻译后显示为[姓名],后面显示一个文本框,让用户可以赋值.
用户可以调用 RUN 方法.调用有参数的 SaySomeThing 方法.
同时,如果是其它对象,下面还会显示该对象的属性这样子..
我知道会用到反射.但具体不知该怎么做最好.
请大佬指点迷津,因为自学 C#,平时就偶尔写写小程序,没有多少经验..所以遇到高级功能就蒙逼了.
1
uubooks OP 类名后面没有括号..我写错了..
|
2
allanpk716 2020-11-07 10:15:05 +08:00 via iPhone
bind 以及实现 covert
|
3
allanpk716 2020-11-07 10:15:46 +08:00 via iPhone
@allanpk716 忘记说了,WPF 的话 doge
|
4
fiveelementgid 2020-11-07 11:13:02 +08:00 via Android
自学+1,反射也没看懂,等一个带佬
还有,不建议你在这里使用自动属性{get;set;} |
5
di1012 2020-11-07 11:13:49 +08:00
//基类
class BaseClass { public int BaseField = 0; } //派生类 class DerivedClass : BaseClass { public int DerivedField = 0; } class Program { static void Main(string[] args) { var bc = new BaseClass(); var dc = new DerivedClass(); BaseClass[] bca = new BaseClass[] { bc, dc }; foreach(var v in bca) { //获取类型 Type t = v.GetType(); Console.WriteLine("Object Type: {0}", t.Name); //获取类中的字段 FieldInfo[] fi = t.GetFields(); foreach (var f in fi) Console.WriteLine(" Field:{0}", f.Name); Console.WriteLine(); } Console.WriteLine("End!"); Console.ReadKey(); } } 网上找的,同理类似,自己研究下就会了 |
6
kiracyan 2020-11-07 11:29:49 +08:00
用 Attribute 标注属性 然后自己实现这个特性 反射的时候根据特性进行自动化
|
7
ian19znj 2020-11-07 11:32:23 +08:00 via iPhone
其实我没太看懂你的需求,不过要用反射取属性的话,这样写,typeofGetProperty(propertyName).GetValue(person)
|
8
ian19znj 2020-11-07 11:33:33 +08:00 via iPhone
写丢了。。Typeof(Person).GetProperty(propertyName).GetValue(person)
|
9
uubooks OP 谢谢楼上各位大佬的解答.
可能我问题描述得不太好.反射那些我知道. 我是想把我的类或接口的内容曝光给用户,让用户来决定相关的操作. 比如汽车类,有 color 属性,speed 属性,start,stop 方法.让用户可以选择颜色.启动汽车. 但这个 color 属性我在 WINFORM 界面针对不同国家用户可能要翻译成[中文,日文,英文]. 而且这个汽车类不是我自己写的类,是别人写的类或接口,所以就蒙了.不知怎么弄.可能要用到特性吧. @allanpk716 @di1012 @kiracyan @ian19znj |
10
beyondex 2020-11-07 13:04:09 +08:00 via Android
没太看明白,如果是多语言,感觉跟反射关系不大,多语言就用多语言的方案,也可以自己用字典实现。
如果需要动态反射操作,可以看下 Clay 这个库 |
11
xuanbg 2020-11-07 13:06:37 +08:00
@uubooks 你这个是本地化需求,和反射他就没关系呀。你在界面上显示 年龄:20 和显示 age:20,逻辑上是一回事。都是把 age 这个属性的值绑定到 age 这个 textbox 上面。至于这个 textbox 前面的文本显示成年龄还是 Age,要看用户选择的界面语言是中文还是英语。
|
12
beyondex 2020-11-07 13:08:50 +08:00 via Android
|
13
onepix 2020-11-07 13:24:59 +08:00 via iPhone
这还用得着反射,我没理解题意吗?!
|
14
chinvo 2020-11-07 13:25:59 +08:00 via iPhone
humanizer
|
15
uubooks OP @onepix 要用到啊.如果只有 1 个 2 个属性,那我直接拖控件就可以了.二个 label 就好了.但是如果我有几十个上百个属性和方法呢.而且这个类对象不是固定的.我可能会操作汽车,动物类这样子.
|
17
chinni 2020-11-07 14:18:08 +08:00
就是根据类定义 生成 控件排列 直接用 attribute 然后挨个读取就行了
|
18
h82258652 2020-11-07 14:53:00 +08:00 1
这个最好还是说一下平台吧,asp.net core 里我倒是知道
```C# public class Person { [Display(Name = "密码")] [DataType(DataType.Password)] public string Password{get;set;} } ``` 然后 Razor 里这样 ``` @Html.Editor(model=>mode.Password) ``` 就会生成<input type="password">类似的代码 Winform 和 WPF 里据我所知是没有的。另外个人观点,与其用反射,不如用代码生成,按你自己的规则把这个类对应的控件代码生成出来,反正运行期间类又不可能会改变的。 |
19
allanpk716 2020-11-07 15:17:14 +08:00
@uubooks 按你的需求 WPF 很容易实现。控件 bind 数据源的属性( Car.Color ),然后通过 bind 的 convert 转换到你想要的语言。用户看到的显示值其实是 covert 的结果,但是选择的其实还是属性的值。所以未必需要反射来实现。
花点时间入门下 WPF 吧,你会发现如果是面向 Windows 桌面开发,WPF 太爽了。看懂 WPF bind 就差不多可以跟 Winform 对着干了。 抛个砖,抄段代码,别纠结于细节(逃 *.cs /// <summary> /// 将性别转换为字符串 /// </summary> public class ConverterSexsAnimal2String : IValueConverter { public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value.ToString() == string.Empty) return SexsAnimalConverter.ToString(Sexs.Unknow); Sexs type = (Sexs)System.Enum.Parse(typeof(Sexs), value.ToString()); return SexsAnimalConverter.ToString(type); } public object ConvertBack(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return null; } } string SexsAnimalConverter.ToString(Sexs sex) { string str; switch (sex) { case Sexs.Male: { // 这里就是多国语言的每个字段对应的 key,具体去看怎么实现多国语言的。 str = ResourceHelper.FindResoure("str_Male"); break; } case Sexs.Female: { str = ResourceHelper.FindResoure("str_Female"); break; } case Sexs.Unknow: { str = ResourceHelper.FindResoure("str_SexUnkonw"); break; } default: str = string.Empty; break; } return str; } 界面 bind .xaml 这里是单向 bind,你得看 Mode 可选项。 <DataGridTextColumn Binding="{Binding Sex,Converter={StaticResource ConverterSexsAnimal2String}, Mode=OneWay}" ....... /> |
20
uubooks OP @allanpk716 谢谢老哥.我回去 看一下.学得不够深入,搞些东西真蒙.
|
21
wangbudong 2020-11-07 15:54:14 +08:00
这关反射什么事
|
22
BigBunny 2020-11-07 18:03:44 +08:00 via iPhone
这个最好使用自定义特性配合使用
|
23
smilenceX 2020-11-07 22:29:37 +08:00
如果你只是需要绑定,前面已经有人说过了
如果你是需要实现一个像 visual studio 的属性编辑器那样的功能,可以在 github 搜 property grid,有相应的实现。 |
24
ian19znj 2020-11-07 23:41:57 +08:00 via iPhone
我明白楼主的意思了,楼上正解,PropertyGrid 应该就是。推荐 Xceed 家的 PropertyGrid,这里附个链接,楼主你看看是不是你想要的。
https://github.com/xceedsoftware/wpftoolkit/wiki/PropertyGrid |
25
forgottencoast 2020-11-18 10:55:58 +08:00
这使用了哪一个框架来做界面的? WinForm 还是 WPF ?还是别的?
如果还没开始,用 WinForm 最简单,什么都不用学,直接获取值给界面赋值就可以了。 |