문제

나에서 작업하 제어를 함께 묶어서 하나 ListView 다른 그래서 그 때 마스터 ListView 스크롤,아이 ListView 보기입 업데이트를 일치합니다.

지금까지 했을 얻을 수 있 아이 ListViews 를 업데이트들을 볼 때 마스터 스크롤 버튼을 클릭합니다.문제는 그 때를 클릭하고 끄는 스크롤 막대 자체,아이 ListViews 이 업데이트되지 않습니다.나는 보았다는 메시지 전송을 사용하여 스파이++고 올바른 메시지가 전송됩니다.

여기에는 현재 코드:

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 기술 포럼도 캡처 및 프로세스 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 스크롤 하지만 변하지 않는 실제 보기에 아이입니다.

그래서 제 질문은:

  1. 가능 업데이트 아이 ListViews 때 마스터 ListView 스크롤 끌?
  2. 그렇다면,어떻게 합니까?
도움이 되었습니까?

해결책

내가 하고 싶은 동일할 것,그 후 찾 주위에 내가 발견 코드,여기에는 도움이지만,물론 문제가 해결되지 않.하지만 그 후에 그것으로,저는 솔루션을 찾았습니다.

키에 왔을 때 깨달았다는 이 스크롤 버튼을 작동하는 데 사용할 수 있는 것을 슬라이 작동합니다.다시 말해서,때 SB_THUMBTRACK 이벤트에,내가 반복되는 문제 SB_LINELEFT 및 SB_LINERIGHT 이벤트까지 내 아이는 ListView 을 마스터입니다.예,이는 완벽하지 않습니다,하지만 그것은 작품을 가까이에 충분하다.

내 경우에는,내 마스터 ListView"라고 reportView 하는 동안,"내 아이 ListView"라고 summaryView".여기에서의 내 적절한 코드:

public class MyListView : ListView
{
    public event ScrollEventHandler HScrollEvent;

    protected override void WndProc(ref System.Windows.Forms.Message msg) 
    {
        if (msg.Msg==WM_HSCROLL && HScrollEvent != null)
            HScrollEvent(this,new ScrollEventArgs(ScrollEventType.ThumbTrack, (int)msg.WParam));

        base.WndProc(ref msg);
    }
}

한 다음의 이벤트 처리기 자체:

reportView.HScrollEvent += new ScrollEventHandler((sender,e) => {
    if ((ushort) e.NewValue != SB_THUMBTRACK)
        SendMessage(summaryView.Handle, WM_HSCROLL, (IntPtr) e.NewValue, IntPtr.Zero);
    else {
        int newPos = e.NewValue >> 16;
        int oldPos = GetScrollPos(reportView .Handle, SB_HORZ);                 
        int pos    = GetScrollPos(summaryView.Handle, SB_HORZ);
        int lst;

        if (pos != newPos)
            if      (pos<newPos && oldPos<newPos) do { lst=pos; SendMessage(summaryView.Handle,WM_HSCROLL,(IntPtr)SB_LINERIGHT,IntPtr.Zero); } while ((pos=GetScrollPos(summaryView.Handle,SB_HORZ)) < newPos && pos!=lst);
            else if (pos>newPos && oldPos>newPos) do { lst=pos; SendMessage(summaryView.Handle,WM_HSCROLL,(IntPtr)SB_LINELEFT, IntPtr.Zero); } while ((pos=GetScrollPos(summaryView.Handle,SB_HORZ)) > newPos && pos!=lst);
        }
    });

죄송에 대한 이상한 포맷의 동안 루프가 있지만,그건 내가 선호하는 코드 같은 것들입니다.

다음 문제가 제거하기로 스크롤 막대 아동 ListView.나는 당신을 발견했던 방법이라고 HideScrollBar.이 정말 작동하지 않았습니다.더 나은 솔루션을 나의 케이스에서 떠나 스크롤 막대가 있지만"덮음"그것을 대신 합니다.내가 이렇게 열 헤더니다.나는 그냥 슬라이드 아동 제어 아래에 마스터 컨트롤 커버를 열고 헤더.그리고 나는 스트레칭 아이가 떨어진 위원회가 포함된다.다음을 제공하기 위하여 국경을 따라 가장자리의 나이 포함된 패널에 던져 컨트롤 커버를 보이는 아래쪽 가장자리의 나는 아이 ListView.그것은 보이는 끝이 오히려 좋다.

또한 추가 이벤트를 처리하는 동기화 변화하는 열에 폭로,:

reportView.ColumnWidthChanging += new ColumnWidthChangingEventHandler((sender,e) => {
    summaryView.Columns[e.ColumnIndex].Width = e.NewWidth;
    });         

이 모든 것이 조금의 임시방편 보,그것이 나를 위해 작동 합니다.

다른 팁

이것은 추측을 얻을 정신적 흐르는 주스 그래서 그것으로 당신은 것입니다:에서 스크롤을 처리기 마스터 목록을 스크롤 핸들러 아이 목록(통과 보낸 사람과시키려면 다음은 마스터로부터)?

추가 이것을 너의 양식 로드:

masterList.Scroll += new ScrollEventHandler(this.masterList_scroll);

를 참조하는 이:

private void masterList_scroll(Object sender, System.ScrollEventArgs e)
{
    childList_scroll(sender, e);
}

private void childList_scroll(Object sender, System.ScrollEventArgs e)
{
   childList.value = e.NewValue
}

나는 내 자신의 클래스를 상속받 ListView 를 노출하는 수직 및 수평 스크롤 이벤트입니다.

그때 나는 할 수 만드 스크롤을 처리기는 나의 형태를 동기화하는 두 개의 컨트롤

이 예제 코드는 허용해야 합니다 목록을 게시하는 스크롤 이벤트:

public class MyListView : System.Windows.Forms.ListView
{
    const int WM_HSCROLL = 0x0114;
    const int WM_VSCROLL = 0x0115;

    private ScrollEventHandler evtHScroll_m;
    private ScrollEventHandler evtVScroll_m;

    public event ScrollEventHandler OnHScroll
    {
        add
        {
            evtHScroll_m += value;
        }
        remove
        {
            evtHScroll_m -= value;
        }
    }

    public event ScrollEventHandler OnHVcroll
    {
        add
        {
            evtVScroll_m += value;
        }
        remove
        {
            evtVScroll_m -= value;
        }
    }

    protected override void WndProc(ref System.Windows.Forms.Message msg) 
    { 
        if (msg.Msg == WM_HSCROLL && evtHScroll_m != null) 
            {
            evtHScroll_m(this,new ScrollEventArgs(ScrollEventType.ThumbTrack, msg.WParam.ToInt32()));
            }

        if (msg.Msg == WM_VSCROLL && evtVScroll_m != null)  
        {
            evtVScroll_m(this, new ScrollEventArgs(ScrollEventType.ThumbTrack, msg.WParam.ToInt32()));
        }
        base.WndProc(ref msg); 
    }

지금 처리하는 스크롤 이벤트에서 당신의 형태:

설 를 방법을 보낼 수 있 windows 메시지를 제어:

[DllImport("user32.dll", CharSet = CharSet.Auto, SetLastError = true)]
    public static extern int SendMessage(IntPtr hWnd, [MarshalAs(UnmanagedType.U4)] int iMsg, int iWParam, int iLParam);

설정의 이벤트 처리기(lstMaster 및 lstChild 는 두 개의 박):

lstMaster.OnVScroll += new ScrollEventHandler(this.lstMaster_OnVScroll);
lstMaster.OnHScroll += new ScrollEventHandler(this.lstMaster_OnHScroll);

const int WM_HSCROLL = 0x0114;      
const int WM_VSCROLL = 0x0115;  

private void lstMaster_OnVScroll(Object sender, System.ScrollEventArgs e)
{    
    SendMessage(lstChild.Handle,WM_VSCROLL,(IntPtr)e.NewValue, IntPtr.Zero); 
}

private void  lstMaster_OnHScroll(Object sender, System.ScrollEventArgs e)
{   
    SendMessage(lstChild.Handle,WM_HSCROLL,(IntPtr)e.NewValue, IntPtr.Zero); 
}

순진한 솔루션을에 문제가 될 수 있습을 처리하는 페인트 메시지가 부모에 목록보기 및 검사하는 경우 연결 목록 보기에 표시하는 정확한 데이터이다.그렇지 않을 경우,그 후 업데이트를 표시하는 정확한 데이터를 호출하여 EnsureVisible 방법입니다.

라이센스 : CC-BY-SA ~와 함께 속성
제휴하지 않습니다 StackOverflow
scroll top