[WPF]ListBoxの選択/スクロール位置を同期(連動)させる


1.)項目の選択を同期する
 項目を選択を同期させるのはXAMLの設定で可能です。
 2つのListBoxを以下のように"IsSynchronizedWithCurrentItem="True"と設定します。
 2つのListBoxが同じデータを参照している場合は選択が同期するようになります。


<ListBox Name="listBox1" Width="120" DockPanel.Dock="Left" IsSynchronizedWithCurrentItem="True" />
<ListBox Name="listBox2" DockPanel.Dock="Left" IsSynchronizedWithCurrentItem="True" />

<C#:データの追加例>

//データを追加する
for (int i = 0; i < 20; ++i)
{
listBox1.Items.Add(string.Format("Item-{0}",i.ToString()));
}
//選択を同期させるため、listBox2のデータをlistBox1を参照するようにする
listBox2.ItemsSource = listBox1.Items; ;

2.)スクロール位置を同期させる
 スクロール位置を同期させるにはListBoxのScrollViewerのイベントハンドラ取得し、イベントを設定する必要があります。この設定はXAMLで行うことができないため、VisualTreeHelperを使用して、ScrollViewerをListBoxから取得する必要があります。
 ScrollViewerを取得するには以下の処理を使用します。
 
<C#:ScrollViewerの取得関数>

private ScrollViewer GetScrollViewer(UIElement uiParent)
{
int nCount = VisualTreeHelper.GetChildrenCount(uiParent);
try
{
for (int i = 0; i < nCount; ++i)
{
UIElement uielement = VisualTreeHelper.GetChild(uiParent, i) as UIElement;
if (uielement.GetType() == typeof(System.Windows.Controls.ScrollViewer))
{
return (ScrollViewer)uielement;
}
ScrollViewer scrollviewer = GetScrollViewer(uielement);
if (scrollviewer != null) return scrollviewer;
}
}
catch (Exception ex)
{
}
return null;
}

 GetScrollViewerを使用して、ListBoxを使用しているウインドウのLoadedハンドラで、ScrollViewerのイベントScrollChangedにハンドラを設定します。

<C#:ScrollViewerのScrollChangedにハンドラを設定する>

void listBox1_ScrollChangedEventHandler(object sender, ScrollChangedEventArgs e)
{
//ListBox1の位置をListBox2と同じにする
m_Scroll2.ScrollToVerticalOffset(m_Scroll1.VerticalOffset);
}
void llistBox2_ScrollChangedEventHandler(object sender, ScrollChangedEventArgs e)
{
//ListBox2の位置をListBox1と同じにする
m_Scroll1.ScrollToVerticalOffset(m_Scroll2.VerticalOffset);
}
private void Window_Loaded(object sender, RoutedEventArgs e)
{
//ScrollViewerのハンドを設定する
m_Scroll1 = GetScrollViewer(listBox1);
if (m_Scroll1 != null)
{
m_Scroll1.ScrollChanged += listBox1_ScrollChangedEventHandler;
}
m_Scroll2 = GetScrollViewer(listBox2);
if (m_Scroll2 != null)
{
m_Scroll2.ScrollChanged += llistBox2_ScrollChangedEventHandler;
}
}

3.)サンプルコード
 完全なサンプルコードは以下からダウンロードしてください。
  AsynchListBox.zip.zip


0 件のコメント :

コメントを投稿