マスターListViewがスクロールされたときに、子ListViewビューが一致するように更新されるように、あるListViewから別のListViewにビューを結び付けるコントロールに取り組んでいます。
これまでのところ、マスタースクロールバーボタンがクリックされたときに子のListViewにビューを更新させることができました。問題は、ScrollBar自体をクリックしてドラッグすると、子のListViewが更新されないことです。Spy ++を使用して送信されているメッセージを確認しましたが、正しいメッセージが送信されています。
これが私の現在のコードです:
public partial class LinkedListViewControl : ListView
{
[DllImport("User32.dll")]
private static extern bool SendMessage(IntPtr hwnd, UInt32 msg, IntPtr wParam, IntPtr lParam);
[DllImport("User32.dll")]
private static extern bool ShowScrollBar(IntPtr hwnd, int wBar, bool bShow);
[DllImport("user32.dll")]
private static extern int SetScrollPos(IntPtr hWnd, int wBar, int nPos, bool bRedraw);
private const int WM_HSCROLL = 0x114;
private const int SB_HORZ = 0;
private const int SB_VERT = 1;
private const int SB_CTL = 2;
private const int SB_BOTH = 3;
private const int SB_THUMBPOSITION = 4;
private const int SB_THUMBTRACK = 5;
private const int SB_ENDSCROLL = 8;
public LinkedListViewControl()
{
InitializeComponent();
}
private readonly List<ListView> _linkedListViews = new List<ListView>();
public void AddLinkedView(ListView listView)
{
if (!_linkedListViews.Contains(listView))
{
_linkedListViews.Add(listView);
HideScrollBar(listView);
}
}
public bool RemoveLinkedView(ListView listView)
{
return _linkedListViews.Remove(listView);
}
private void HideScrollBar(ListView listView)
{
//Make sure the list view is scrollable
listView.Scrollable = true;
//Then hide the scroll bar
ShowScrollBar(listView.Handle, SB_BOTH, false);
}
protected override void WndProc(ref Message msg)
{
if (_linkedListViews.Count > 0)
{
//Look for WM_HSCROLL messages
if (msg.Msg == WM_HSCROLL)
{
foreach (ListView view in _linkedListViews)
{
SendMessage(view.Handle, WM_HSCROLL, msg.WParam, IntPtr.Zero);
}
}
}
}
}
MS Tech Forumsのこの投稿に基づいて、SB_THUMBTRACKイベントをキャプチャして処理しようとしました。
protected override void WndProc(ref Message msg)
{
if (_linkedListViews.Count > 0)
{
//Look for WM_HSCROLL messages
if (msg.Msg == WM_HSCROLL)
{
Int16 hi = (Int16)((int)msg.WParam >> 16);
Int16 lo = (Int16)msg.WParam;
foreach (ListView view in _linkedListViews)
{
if (lo == SB_THUMBTRACK)
{
SetScrollPos(view.Handle, SB_HORZ, hi, true);
int wParam = 4 + 0x10000 * hi;
SendMessage(view.Handle, WM_HSCROLL, (IntPtr)(wParam), IntPtr.Zero);
}
else
{
SendMessage(view.Handle, WM_HSCROLL, msg.WParam, IntPtr.Zero);
}
}
}
}
// Pass message to default handler.
base.WndProc(ref msg);
}
これにより、子のListView ScrollBarの場所が更新されますが、子の実際のビューは変更されません。
だから私の質問は:
- マスターのListViewScrollBarをドラッグしたときに、子のListViewを更新することはできますか?
- もしそうなら、どのように?