如何在虚拟模式下设置listviewitem的第一项属性?
how to set the top item property of listviewitem when it is in virtual mode?
public new int VirtualListSize
{
get { return base.VirtualListSize; }
set
{
// If the new size is smaller than the Index of TopItem, we need to make
// sure the new TopItem is set to something smaller.
if (VirtualMode &&
View == View.Details &&
TopItem != null &&
value > 0 &&
TopItem.Index > value - 1)
{
TopItem = Items[value - 1];
}
base.VirtualListSize = value;
}
}
我正在尝试设置列表视图的topitem 属性,但是在虚拟模式下项目被禁用。所以任何试图在虚拟模式下访问它的代码都会抛出一个 invalidoperation 异常。当我尝试逐行调试时不会发生异常。如果我注释行 TopItem=Items[value-1]
它不会抛出任何异常。
System.InvalidOperationException:在 VirtualMode 中时,ListView RetrieveVirtualListItem 事件需要每个 ListView 列的列表视图 SubItem。
在 System.Windows.Forms.ListView.WmReflectNotify(消息& m)
在 System.Windows.Forms.ListView.WndProc(留言& m)
在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam)
请建议。
当虚拟列表大小变小时,您无需更改 TopItem
。 .NET ListView
已经做到了。根据 dotPeek 反汇编程序:
public int VirtualListSize {
...
set {
...
bool keepTopItem = this.IsHandleCreated && VirtualMode && this.View == View.Details && !this.DesignMode;
int topIndex = -1;
if (keepTopItem) {
topIndex = unchecked( (int) (long)SendMessage(NativeMethods.LVM_GETTOPINDEX, 0, 0));
}
virtualListSize = value;
if (IsHandleCreated && VirtualMode && !DesignMode)
SendMessage(NativeMethods.LVM_SETITEMCOUNT, virtualListSize, 0);
if (keepTopItem) {
topIndex = Math.Min(topIndex, this.VirtualListSize - 1);
// After setting the virtual list size ComCtl makes the first item the top item.
// So we set the top item only if it wasn't the first item to begin with.
if (topIndex > 0) {
ListViewItem lvItem = this.Items[topIndex];
this.TopItem = lvItem;
}
}
}
}
这个问题在于,根据我的经验,在虚拟列表视图上设置 TopItem
很容易出错 activity。在我的代码中我有这个块:
// Damn this is a pain! There are cases where this can also throw exceptions!
try {
this.listview.TopItem = lvi;
}
catch (Exception) {
// Ignore any failures
}
由于设置 TopItem
有时会抛出异常,这意味着有时设置 VirtualListSize
也会类似地抛出异常。
其他点
您 可以 通过 索引 访问 Items
集合,即使在虚拟模式下也是如此。所以,这很好(假设列表不为空):
this.listview1.TopItem = this.listview1.Items[this.listview1.Items.Count - 1];
您不能在虚拟模式下迭代Items
集合。这将引发异常:
foreach (ListViewItem item in this.listview1.Items) { ... }
public new int VirtualListSize
{
get { return base.VirtualListSize; }
set
{
// If the new size is smaller than the Index of TopItem, we need to make
// sure the new TopItem is set to something smaller.
if (VirtualMode &&
View == View.Details &&
TopItem != null &&
value > 0 &&
TopItem.Index > value - 1)
{
TopItem = Items[value - 1];
}
base.VirtualListSize = value;
}
}
我正在尝试设置列表视图的topitem 属性,但是在虚拟模式下项目被禁用。所以任何试图在虚拟模式下访问它的代码都会抛出一个 invalidoperation 异常。当我尝试逐行调试时不会发生异常。如果我注释行 TopItem=Items[value-1]
它不会抛出任何异常。
System.InvalidOperationException:在 VirtualMode 中时,ListView RetrieveVirtualListItem 事件需要每个 ListView 列的列表视图 SubItem。 在 System.Windows.Forms.ListView.WmReflectNotify(消息& m) 在 System.Windows.Forms.ListView.WndProc(留言& m) 在 System.Windows.Forms.NativeWindow.Callback(IntPtr hWnd, Int32 msg, IntPtr wparam, IntPtr lparam) 请建议。
当虚拟列表大小变小时,您无需更改 TopItem
。 .NET ListView
已经做到了。根据 dotPeek 反汇编程序:
public int VirtualListSize {
...
set {
...
bool keepTopItem = this.IsHandleCreated && VirtualMode && this.View == View.Details && !this.DesignMode;
int topIndex = -1;
if (keepTopItem) {
topIndex = unchecked( (int) (long)SendMessage(NativeMethods.LVM_GETTOPINDEX, 0, 0));
}
virtualListSize = value;
if (IsHandleCreated && VirtualMode && !DesignMode)
SendMessage(NativeMethods.LVM_SETITEMCOUNT, virtualListSize, 0);
if (keepTopItem) {
topIndex = Math.Min(topIndex, this.VirtualListSize - 1);
// After setting the virtual list size ComCtl makes the first item the top item.
// So we set the top item only if it wasn't the first item to begin with.
if (topIndex > 0) {
ListViewItem lvItem = this.Items[topIndex];
this.TopItem = lvItem;
}
}
}
}
这个问题在于,根据我的经验,在虚拟列表视图上设置 TopItem
很容易出错 activity。在我的代码中我有这个块:
// Damn this is a pain! There are cases where this can also throw exceptions!
try {
this.listview.TopItem = lvi;
}
catch (Exception) {
// Ignore any failures
}
由于设置 TopItem
有时会抛出异常,这意味着有时设置 VirtualListSize
也会类似地抛出异常。
其他点
您 可以 通过 索引 访问 Items
集合,即使在虚拟模式下也是如此。所以,这很好(假设列表不为空):
this.listview1.TopItem = this.listview1.Items[this.listview1.Items.Count - 1];
您不能在虚拟模式下迭代Items
集合。这将引发异常:
foreach (ListViewItem item in this.listview1.Items) { ... }