为什么不在我的 DynamicObject 上调用 TryGetMember?
Why is TryGetMember not invoked on my DynamicObject?
我有以下 class 用于绑定到 WPF DataGrid
上动态生成的列。列绑定必须是 属性 名称,我可以将适当命名的属性添加到 DynamicObject
:
public class BindableDynamicDictionary : DynamicObject
{
private readonly Dictionary<string, object> _dictionary;
public BindableDynamicDictionary()
{
_dictionary = new Dictionary<string, object>();
}
public object this[string key]
{
get { return _dictionary[key]; }
set { _dictionary[key] = value; }
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dictionary[binder.Name] = value;
return true;
}
}
仅供参考,每天 属性 存储一个 AppointmentRowViewModel
。
当我为一周中的每一天使用一个动态 属性 填充上述实例时,所有动态属性都会列出,并且字典访问工作正常,但是 属性名称访问会引发异常。例如(来自我的即时 Window):
apptDynamic.GetDynamicMemberNames()
Count = 9
[0]: "20161205"
[1]: "Monday"
[2]: "20161206"
[3]: "Tuesday"
[4]: "20161208"
[5]: "Thursday"
[6]: "20161211"
[7]: "Sunday"
[8]: "20161215"
apptDynamic.Monday
error CS1061: 'AppointmentCalendarViewModel.TimeAppointmentDictionary' does not contain a definition for 'Monday' and no extension method 'Monday' accepting a first argument of type 'AppointmentCalendarViewModel.TimeAppointmentDictionary' could be found (are you missing a using directive or an assembly reference?)
apptDynamic["Monday"]
{ApptEase.Client.Prism.CSharp.ViewModels.AppointmentRowViewModel}
这可能是因为我只使用字典访问设置属性?我不知道如果没有 属性 名称字面量怎么办,所以我这样做:
BindableDynamicDictionary apptDynamic = Appointments[start];
DateTime loopDate = ActiveDate.FirstDayOfWeek(WeekStartDay);
for (var i = 0; i < DaysVisible; i++)
{
loopDate = loopDate.AddDays(i);
if (appt.StartDateTime.Date == loopDate.Date)
{
apptDynamic[loopDate.ToString("yyyyMMdd")] = appt;
apptDynamic[loopDate.DayOfWeek.ToString()] = appt;
continue;
}
apptDynamic[loopDate.ToString("yyyyMMdd")] = null;
apptDynamic[loopDate.DayOfWeek.ToString()] = null;
}
其中 ActiveDate.FirstDayOfWeek(WeekStartDay)
使用 DateTime
扩展方法获取 ActiveDate
所在一周的第一天的日期,具体取决于一周的开始日期。
我认为 DynamicObject
的部分主要思想是能够使用它的键访问字典项目,就好像它是 属性 名称一样。为什么这对我不起作用?
由于我的代表率低,我无法添加评论,所以我会留下答案。
从您提供的代码示例中,我只能看到您将动态对象存储为
的方式
BindableDynamicDictionary apptDynamic = Appointments[start];
对于动态属性访问工作你需要使用动态关键字
dynamic apptDynamic = Appointments[start];
参考链接
https://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetmember(v=vs.110).aspx
Differences between ExpandoObject, DynamicObject and dynamic
我有以下 class 用于绑定到 WPF DataGrid
上动态生成的列。列绑定必须是 属性 名称,我可以将适当命名的属性添加到 DynamicObject
:
public class BindableDynamicDictionary : DynamicObject
{
private readonly Dictionary<string, object> _dictionary;
public BindableDynamicDictionary()
{
_dictionary = new Dictionary<string, object>();
}
public object this[string key]
{
get { return _dictionary[key]; }
set { _dictionary[key] = value; }
}
public override bool TryGetMember(GetMemberBinder binder, out object result)
{
return _dictionary.TryGetValue(binder.Name, out result);
}
public override bool TrySetMember(SetMemberBinder binder, object value)
{
_dictionary[binder.Name] = value;
return true;
}
}
仅供参考,每天 属性 存储一个 AppointmentRowViewModel
。
当我为一周中的每一天使用一个动态 属性 填充上述实例时,所有动态属性都会列出,并且字典访问工作正常,但是 属性名称访问会引发异常。例如(来自我的即时 Window):
apptDynamic.GetDynamicMemberNames()
Count = 9
[0]: "20161205"
[1]: "Monday"
[2]: "20161206"
[3]: "Tuesday"
[4]: "20161208"
[5]: "Thursday"
[6]: "20161211"
[7]: "Sunday"
[8]: "20161215"
apptDynamic.Monday
error CS1061: 'AppointmentCalendarViewModel.TimeAppointmentDictionary' does not contain a definition for 'Monday' and no extension method 'Monday' accepting a first argument of type 'AppointmentCalendarViewModel.TimeAppointmentDictionary' could be found (are you missing a using directive or an assembly reference?)
apptDynamic["Monday"]
{ApptEase.Client.Prism.CSharp.ViewModels.AppointmentRowViewModel}
这可能是因为我只使用字典访问设置属性?我不知道如果没有 属性 名称字面量怎么办,所以我这样做:
BindableDynamicDictionary apptDynamic = Appointments[start];
DateTime loopDate = ActiveDate.FirstDayOfWeek(WeekStartDay);
for (var i = 0; i < DaysVisible; i++)
{
loopDate = loopDate.AddDays(i);
if (appt.StartDateTime.Date == loopDate.Date)
{
apptDynamic[loopDate.ToString("yyyyMMdd")] = appt;
apptDynamic[loopDate.DayOfWeek.ToString()] = appt;
continue;
}
apptDynamic[loopDate.ToString("yyyyMMdd")] = null;
apptDynamic[loopDate.DayOfWeek.ToString()] = null;
}
其中 ActiveDate.FirstDayOfWeek(WeekStartDay)
使用 DateTime
扩展方法获取 ActiveDate
所在一周的第一天的日期,具体取决于一周的开始日期。
我认为 DynamicObject
的部分主要思想是能够使用它的键访问字典项目,就好像它是 属性 名称一样。为什么这对我不起作用?
由于我的代表率低,我无法添加评论,所以我会留下答案。
从您提供的代码示例中,我只能看到您将动态对象存储为
的方式BindableDynamicDictionary apptDynamic = Appointments[start];
对于动态属性访问工作你需要使用动态关键字
dynamic apptDynamic = Appointments[start];
参考链接
https://msdn.microsoft.com/en-us/library/system.dynamic.dynamicobject.trygetmember(v=vs.110).aspx
Differences between ExpandoObject, DynamicObject and dynamic