2009-07-11 11 views
2

私はWPFでMVVMパターンを実装しようとしています。私はジェレミー・アレスのVery simple MVVM demo applicationに従った。リストボックスのスクロールバーが選択された項目(ICollectionView)に従わない

<ListBox 
    Name="myListBox" 
    IsSynchronizedWithCurrentItem="True" 
    ItemsSource="{Binding Persons}"> 
    <ListBox.ItemTemplate> 
     <DataTemplate> 
      <views:PersonsView /> 
     </DataTemplate> 
    </ListBox.ItemTemplate> 
</ListBox> 

が、私はリストボックスで選択した項目を管理するためになICollectionViewを追加しました:私はのObservableCollectionに結合しているリストボックスを持っています。また、リスト内の前の項目と次の項目を選択できる2つのボタンがあります。

private void GoToPrevious() 
{ 
    this.collectionView.MoveCurrentToPrevious(); 
} 
private void GoToNext() 
{ 
    this.collectionView.MoveCurrentToNext(); 
} 

これは、すべての素晴らしい作品、選択した項目がリストボックスの表示領域の下にあるときただし、リストボックスのスクロールバーがそれに応じて移動しません。

リストボックスのスクロールバー/表示領域を選択したアイテムと同期させるにはどうすればよいですか?

答えて

6

私は答えを見つけました。 は、私はこの問題は、私はMVVMを実装していますように私は、任意のコードビハインドを追加したいなかったということでした

myListBoxItem.BringIntoView(); 

を使用する必要がありました。

解決策は、添付の動作を使用しています。ジョシュ・スミス氏はこれに関する素晴らしい記事を持っています:Introduction to Attached Behaviors in WPF

が、私はリストボックス内の項目のスタイルにセッターをadedd:それは作品

public static class ListBoxItemBehavior 
{ 
    #region IsBroughtIntoViewWhenSelected 

    public static bool GetIsBroughtIntoViewWhenSelected(ListBoxItem listBoxItem) 
    { 
     return (bool)listBoxItem.GetValue(IsBroughtIntoViewWhenSelectedProperty); 
    } 

    public static void SetIsBroughtIntoViewWhenSelected(
     ListBoxItem listBoxItem, bool value) 
    { 
     listBoxItem.SetValue(IsBroughtIntoViewWhenSelectedProperty, value); 
    } 

    public static readonly DependencyProperty IsBroughtIntoViewWhenSelectedProperty = 
     DependencyProperty.RegisterAttached(
     "IsBroughtIntoViewWhenSelected", 
     typeof(bool), 
     typeof(ListBoxItemBehavior), 
     new UIPropertyMetadata(false, OnIsBroughtIntoViewWhenSelectedChanged)); 

    static void OnIsBroughtIntoViewWhenSelectedChanged(
     DependencyObject depObj, DependencyPropertyChangedEventArgs e) 
    { 
     ListBoxItem item = depObj as ListBoxItem; 
     if (item == null) 
      return; 

     if (e.NewValue is bool == false) 
      return; 

     if ((bool)e.NewValue) 
      item.Selected += OnListBoxItemSelected; 
     else 
      item.Selected -= OnListBoxItemSelected; 
    } 

    static void OnListBoxItemSelected(object sender, RoutedEventArgs e) 
    { 
     // Only react to the Selected event raised by the ListBoxItem 
     // whose IsSelected property was modified. Ignore all ancestors 
     // who are merely reporting that a descendant's Selected fired. 
     if (!Object.ReferenceEquals(sender, e.OriginalSource)) 
      return; 

     ListBoxItem item = e.OriginalSource as ListBoxItem; 
     if (item != null) 
      item.BringIntoView(); 
    } 

    #endregion // IsBroughtIntoViewWhenSelected 
} 

<ListBox.ItemContainerStyle> 
    <Style TargetType="{x:Type ListBoxItem}"> 
     <Setter 
      Property="custom:ListBoxItemBehavior.IsBroughtIntoViewWhenSelected" 
      Value="True" /> 
    </Style> 
</ListBox.ItemContainerStyle> 

、以下のクラスを追加(唯一のListBoxにジョシュの記事からツリービューを変更) !!

関連する問題