{
public sealed class DetailsListView : ListView
{
+ private Rectangle changeBounds;
private EventHandlerList _handlers = new EventHandlerList();
public event EventHandler VScrolled;
public void ChangeSubItemBackColor(int itemIndex, int subitemIndex, Color backColor)
{
- this.Items[itemIndex].SubItems[subitemIndex].BackColor = backColor;
+ var item = this.Items[itemIndex];
+ item.SubItems[subitemIndex].BackColor = backColor;
+ SetUpdateBounds(item, subitemIndex);
+ this.Update();
+ this.changeBounds = Rectangle.Empty;
}
public void ChangeSubItemForeColor(int itemIndex, int subitemIndex, Color foreColor)
{
- this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor;
+ var item = this.Items[itemIndex];
+ item.SubItems[subitemIndex].ForeColor = foreColor;
+ SetUpdateBounds(item, subitemIndex);
+ this.Update();
+ this.changeBounds = Rectangle.Empty;
}
public void ChangeSubItemFont(int itemIndex, int subitemIndex, Font fnt)
{
- this.Items[itemIndex].SubItems[subitemIndex].Font = fnt;
+ var item = this.Items[itemIndex];
+ item.SubItems[subitemIndex].Font = fnt;
+ SetUpdateBounds(item, subitemIndex);
+ this.Update();
+ this.changeBounds = Rectangle.Empty;
}
public void ChangeSubItemFontAndColor(int itemIndex, int subitemIndex, Color foreColor, Font fnt)
{
- this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor;
- this.Items[itemIndex].SubItems[subitemIndex].Font = fnt;
+ var item = this.Items[itemIndex];
+ var subItem = item.SubItems[subitemIndex];
+ subItem.ForeColor = foreColor;
+ subItem.Font = fnt;
+ SetUpdateBounds(item, subitemIndex);
+ this.Update();
+ this.changeBounds = Rectangle.Empty;
}
public void ChangeSubItemStyles(int itemIndex, int subitemIndex, Color backColor, Color foreColor, Font fnt)
{
- this.Items[itemIndex].SubItems[subitemIndex].BackColor = backColor;
- this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor;
- this.Items[itemIndex].SubItems[subitemIndex].Font = fnt;
+ var item = this.Items[itemIndex];
+ var subItem = item.SubItems[subitemIndex];
+ subItem.BackColor = backColor;
+ subItem.ForeColor = foreColor;
+ subItem.Font = fnt;
+ SetUpdateBounds(item, subitemIndex);
+ this.Update();
+ this.changeBounds = Rectangle.Empty;
+ }
+
+ private void SetUpdateBounds(ListViewItem item, int subItemIndex)
+ {
+ try
+ {
+ if (subItemIndex > this.Columns.Count)
+ {
+ throw new ArgumentOutOfRangeException("subItemIndex");
+ }
+ if (item.UseItemStyleForSubItems)
+ {
+ this.changeBounds = item.Bounds;
+ }
+ else
+ {
+ this.changeBounds = this.GetSubItemBounds(item, subItemIndex);
+ }
+ }
+ catch (ArgumentException)
+ {
+ //タイミングによりBoundsプロパティが取れない?
+ this.changeBounds = Rectangle.Empty;
+ }
+ }
+
+ private Rectangle GetSubItemBounds(ListViewItem item, int subitemIndex)
+ {
+ if (subitemIndex == 0 && this.Columns.Count > 0)
+ {
+ Rectangle col0 = item.Bounds;
+ return new Rectangle(col0.Left, col0.Top, item.SubItems[1].Bounds.X + 1, col0.Height);
+ }
+ else
+ {
+ return item.SubItems[subitemIndex].Bounds;
+ }
}
[StructLayout(LayoutKind.Sequential)]
[DebuggerStepThrough()]
protected override void WndProc(ref Message m)
{
+ const int WM_ERASEBKGND = 0x14;
+ const int WM_PAINT = 0xF;
const int WM_MOUSEWHEEL = 0x20A;
const int WM_MOUSEHWHEEL = 0x20E;
const int WM_HSCROLL = 0x114;
switch (m.Msg)
{
+ case WM_ERASEBKGND:
+ if (this.changeBounds != Rectangle.Empty)
+ m.Msg = 0;
+ break;
+ case WM_PAINT:
+ if (this.changeBounds != Rectangle.Empty)
+ {
+ Win32Api.ValidateRect(this.Handle, IntPtr.Zero);
+ this.Invalidate(this.changeBounds);
+ this.changeBounds = Rectangle.Empty;
+ }
+ break;
case WM_HSCROLL:
if (HScrolled != null)
HScrolled(this, EventArgs.Empty);
if (_post == null) return;
- var itemColorTuple = new Tuple<ListViewItem, Color>[] { };
+ var itemColors = new Color[] { };
+ int itemIndex = -1;
this.itemCacheLock.EnterReadLock();
try
var query =
from i in Enumerable.Range(0, this._itemCache.Length)
- select new Tuple<ListViewItem, Color>(this._itemCache[i], this.JudgeColor(_post, this._postCache[i]));
+ select this.JudgeColor(_post, this._postCache[i]);
- itemColorTuple = query.ToArray();
+ itemColors = query.ToArray();
+ itemIndex = _itemCacheIndex;
}
finally { this.itemCacheLock.ExitReadLock(); }
- foreach (var tuple in itemColorTuple)
+ if (itemIndex < 0) return;
+
+ foreach (var backColor in itemColors)
{
// この処理中に MyList_CacheVirtualItems が呼ばれることがあるため、
// 同一スレッド内での二重ロックを避けるためにロックの外で実行する必要がある
- tuple.Item1.SubItems[0].BackColor = tuple.Item2;
+ _curList.ChangeItemBackColor(itemIndex++, backColor);
}
}