今天意外的发现struct与class之间的一些区别。就是这些区别导致了在使用这两个类型的数据作为ListPicker的ItemSource时的效果不一样。
(1)使用struct类型对象作为ListPicker的ItemSource
首先定义了一个这样一个struct结构体:
public struct MonthListPickerItem
{
public long Month;
public bool IsLunarMonth;
public MonthListPickerItem(long month, bool isLunarMonth)
{
Month = month;
IsLunarMonth = isLunarMonth;
}
};
然后这样使用它:
public partial class MonthListPicker : UserControl
{
#region Constants
private int January = 1;
private int December = 12;
private int MonthsInYear = 12;
#endregion
#region Data Members
private List<MonthListPickerItem> m_SelectedItems;
#endregion
#region Constructor
public MonthListPicker()
{
InitializeComponent();
m_SelectedItems = new List<MonthListPickerItem>();
m_Era = Era.Solar;
}
#endregion
#region Public Properties
public List<MonthListPickerItem> SelectedItems
{
get
{
List<MonthListPickerItem> copy = new List<MonthListPickerItem>();
copy.AddRange(m_SelectedItems);
return copy;
}
set
{
if (!m_SelectedItems.Equals(value))
{
m_SelectedItems.Clear();
m_SelectedItems.AddRange(value);
}
}
}
public Era Era
{
get
{
return (Era)m_Era;
}
set
{
if (m_Era != value)
{
m_Era = value; NotifyEraPropertyChanged(value);
}
}
}
#endregion
#region Event Handlers
private void InitMonthLP()
{
List<MonthListPickerItem> monthsOfYear = new List<MonthListPickerItem>();
bool isLunarMonth = (Era == Era.Lunar);
for (int i = January; i <= December; ++i)
{
monthsOfYear.Add(new MonthListPickerItem(i, isLunarMonth));
}
MonthLP.ItemsSource = monthsOfYear; // 设置itemsource为12个月份
MonthLP.SelectedItems = m_SelectedItems; // 设置选中的月份
}
private void NotifyEraPropertyChanged(Era era)
{
// do something
}
#endregion
}
这样的代码运行起来时没有问题的,ListPicker的SelectedItems会有选中效果。
(2)使用class类型对象作为ListPicker的ItemSource
但是当我将MonthListPickerItem改为class类型时,代码没有编译错误,但是在运行时设置SelectedItems没有效果,也就是没有item被选中。
例如:
public class MonthListPickerItem
{
public long Month{get;set;}
public bool IsLunarMonth{get;set;}
public MonthListPickerItem(long month, bool isLunarMonth)
{
Month = month;
IsLunarMonth = isLunarMonth;
}
};
这到底是什么原因呢?
struct对象是在栈上创建的,而class对象则是在堆上创建的。在堆上创建的对象在数据块索引和地址空间方面会不一样,即使存储的内容一样;程序在设置选中项的时候,估计是这些方面做了判断,只要是class类型对象使用了new,实际上它们就永远不相等,因此也就是找不到要默认选中的选项。
因此会出现这样的选中项设置无效的情况吧。
------------------------------------------------------------------------------------------------------
但目前没有深究这些问题,实际情况是不是上面所说的这样也不能保证,先作为一个笔记吧,有时间再来确定一下。