開発に使用するリポジトリ
Revision | a78351f21d52abd582cb699cd0e95322d99e52f5 (tree) |
---|---|
Time | 2013-06-19 21:31:54 |
Author | spx <spx268@gmai...> |
Commiter | spx |
DetailsListView の再描画範囲を制御する処理を元に戻した
1.0.9 相当
@@ -38,6 +38,7 @@ namespace OpenTween.OpenTweenCustomControl | ||
38 | 38 | { |
39 | 39 | public sealed class DetailsListView : ListView |
40 | 40 | { |
41 | + private Rectangle changeBounds; | |
41 | 42 | private EventHandlerList _handlers = new EventHandlerList(); |
42 | 43 | |
43 | 44 | public event EventHandler VScrolled; |
@@ -122,30 +123,89 @@ namespace OpenTween.OpenTweenCustomControl | ||
122 | 123 | |
123 | 124 | public void ChangeSubItemBackColor(int itemIndex, int subitemIndex, Color backColor) |
124 | 125 | { |
125 | - this.Items[itemIndex].SubItems[subitemIndex].BackColor = backColor; | |
126 | + var item = this.Items[itemIndex]; | |
127 | + item.SubItems[subitemIndex].BackColor = backColor; | |
128 | + SetUpdateBounds(item, subitemIndex); | |
129 | + this.Update(); | |
130 | + this.changeBounds = Rectangle.Empty; | |
126 | 131 | } |
127 | 132 | |
128 | 133 | public void ChangeSubItemForeColor(int itemIndex, int subitemIndex, Color foreColor) |
129 | 134 | { |
130 | - this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor; | |
135 | + var item = this.Items[itemIndex]; | |
136 | + item.SubItems[subitemIndex].ForeColor = foreColor; | |
137 | + SetUpdateBounds(item, subitemIndex); | |
138 | + this.Update(); | |
139 | + this.changeBounds = Rectangle.Empty; | |
131 | 140 | } |
132 | 141 | |
133 | 142 | public void ChangeSubItemFont(int itemIndex, int subitemIndex, Font fnt) |
134 | 143 | { |
135 | - this.Items[itemIndex].SubItems[subitemIndex].Font = fnt; | |
144 | + var item = this.Items[itemIndex]; | |
145 | + item.SubItems[subitemIndex].Font = fnt; | |
146 | + SetUpdateBounds(item, subitemIndex); | |
147 | + this.Update(); | |
148 | + this.changeBounds = Rectangle.Empty; | |
136 | 149 | } |
137 | 150 | |
138 | 151 | public void ChangeSubItemFontAndColor(int itemIndex, int subitemIndex, Color foreColor, Font fnt) |
139 | 152 | { |
140 | - this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor; | |
141 | - this.Items[itemIndex].SubItems[subitemIndex].Font = fnt; | |
153 | + var item = this.Items[itemIndex]; | |
154 | + var subItem = item.SubItems[subitemIndex]; | |
155 | + subItem.ForeColor = foreColor; | |
156 | + subItem.Font = fnt; | |
157 | + SetUpdateBounds(item, subitemIndex); | |
158 | + this.Update(); | |
159 | + this.changeBounds = Rectangle.Empty; | |
142 | 160 | } |
143 | 161 | |
144 | 162 | public void ChangeSubItemStyles(int itemIndex, int subitemIndex, Color backColor, Color foreColor, Font fnt) |
145 | 163 | { |
146 | - this.Items[itemIndex].SubItems[subitemIndex].BackColor = backColor; | |
147 | - this.Items[itemIndex].SubItems[subitemIndex].ForeColor = foreColor; | |
148 | - this.Items[itemIndex].SubItems[subitemIndex].Font = fnt; | |
164 | + var item = this.Items[itemIndex]; | |
165 | + var subItem = item.SubItems[subitemIndex]; | |
166 | + subItem.BackColor = backColor; | |
167 | + subItem.ForeColor = foreColor; | |
168 | + subItem.Font = fnt; | |
169 | + SetUpdateBounds(item, subitemIndex); | |
170 | + this.Update(); | |
171 | + this.changeBounds = Rectangle.Empty; | |
172 | + } | |
173 | + | |
174 | + private void SetUpdateBounds(ListViewItem item, int subItemIndex) | |
175 | + { | |
176 | + try | |
177 | + { | |
178 | + if (subItemIndex > this.Columns.Count) | |
179 | + { | |
180 | + throw new ArgumentOutOfRangeException("subItemIndex"); | |
181 | + } | |
182 | + if (item.UseItemStyleForSubItems) | |
183 | + { | |
184 | + this.changeBounds = item.Bounds; | |
185 | + } | |
186 | + else | |
187 | + { | |
188 | + this.changeBounds = this.GetSubItemBounds(item, subItemIndex); | |
189 | + } | |
190 | + } | |
191 | + catch (ArgumentException) | |
192 | + { | |
193 | + //タイミングによりBoundsプロパティが取れない? | |
194 | + this.changeBounds = Rectangle.Empty; | |
195 | + } | |
196 | + } | |
197 | + | |
198 | + private Rectangle GetSubItemBounds(ListViewItem item, int subitemIndex) | |
199 | + { | |
200 | + if (subitemIndex == 0 && this.Columns.Count > 0) | |
201 | + { | |
202 | + Rectangle col0 = item.Bounds; | |
203 | + return new Rectangle(col0.Left, col0.Top, item.SubItems[1].Bounds.X + 1, col0.Height); | |
204 | + } | |
205 | + else | |
206 | + { | |
207 | + return item.SubItems[subitemIndex].Bounds; | |
208 | + } | |
149 | 209 | } |
150 | 210 | |
151 | 211 | [StructLayout(LayoutKind.Sequential)] |
@@ -189,6 +249,8 @@ namespace OpenTween.OpenTweenCustomControl | ||
189 | 249 | [DebuggerStepThrough()] |
190 | 250 | protected override void WndProc(ref Message m) |
191 | 251 | { |
252 | + const int WM_ERASEBKGND = 0x14; | |
253 | + const int WM_PAINT = 0xF; | |
192 | 254 | const int WM_MOUSEWHEEL = 0x20A; |
193 | 255 | const int WM_MOUSEHWHEEL = 0x20E; |
194 | 256 | const int WM_HSCROLL = 0x114; |
@@ -203,6 +265,18 @@ namespace OpenTween.OpenTweenCustomControl | ||
203 | 265 | |
204 | 266 | switch (m.Msg) |
205 | 267 | { |
268 | + case WM_ERASEBKGND: | |
269 | + if (this.changeBounds != Rectangle.Empty) | |
270 | + m.Msg = 0; | |
271 | + break; | |
272 | + case WM_PAINT: | |
273 | + if (this.changeBounds != Rectangle.Empty) | |
274 | + { | |
275 | + Win32Api.ValidateRect(this.Handle, IntPtr.Zero); | |
276 | + this.Invalidate(this.changeBounds); | |
277 | + this.changeBounds = Rectangle.Empty; | |
278 | + } | |
279 | + break; | |
206 | 280 | case WM_HSCROLL: |
207 | 281 | if (HScrolled != null) |
208 | 282 | HScrolled(this, EventArgs.Empty); |
@@ -2055,7 +2055,8 @@ namespace OpenTween | ||
2055 | 2055 | |
2056 | 2056 | if (_post == null) return; |
2057 | 2057 | |
2058 | - var itemColorTuple = new Tuple<ListViewItem, Color>[] { }; | |
2058 | + var itemColors = new Color[] { }; | |
2059 | + int itemIndex = -1; | |
2059 | 2060 | |
2060 | 2061 | this.itemCacheLock.EnterReadLock(); |
2061 | 2062 | try |
@@ -2064,17 +2065,20 @@ namespace OpenTween | ||
2064 | 2065 | |
2065 | 2066 | var query = |
2066 | 2067 | from i in Enumerable.Range(0, this._itemCache.Length) |
2067 | - select new Tuple<ListViewItem, Color>(this._itemCache[i], this.JudgeColor(_post, this._postCache[i])); | |
2068 | + select this.JudgeColor(_post, this._postCache[i]); | |
2068 | 2069 | |
2069 | - itemColorTuple = query.ToArray(); | |
2070 | + itemColors = query.ToArray(); | |
2071 | + itemIndex = _itemCacheIndex; | |
2070 | 2072 | } |
2071 | 2073 | finally { this.itemCacheLock.ExitReadLock(); } |
2072 | 2074 | |
2073 | - foreach (var tuple in itemColorTuple) | |
2075 | + if (itemIndex < 0) return; | |
2076 | + | |
2077 | + foreach (var backColor in itemColors) | |
2074 | 2078 | { |
2075 | 2079 | // この処理中に MyList_CacheVirtualItems が呼ばれることがあるため、 |
2076 | 2080 | // 同一スレッド内での二重ロックを避けるためにロックの外で実行する必要がある |
2077 | - tuple.Item1.SubItems[0].BackColor = tuple.Item2; | |
2081 | + _curList.ChangeItemBackColor(itemIndex++, backColor); | |
2078 | 2082 | } |
2079 | 2083 | } |
2080 | 2084 |
@@ -546,6 +546,11 @@ namespace OpenTween | ||
546 | 546 | private const Int32 FLASHW_TIMERNOFG = 0xC; |
547 | 547 | #endregion |
548 | 548 | |
549 | + [DllImport("user32.dll")] | |
550 | + public static extern bool ValidateRect( | |
551 | + IntPtr hwnd, | |
552 | + IntPtr rect); | |
553 | + | |
549 | 554 | #region "スクリーンセーバー起動中か判定" |
550 | 555 | [DllImport("user32", CharSet = CharSet.Auto)] |
551 | 556 | private static extern int SystemParametersInfo( |