2012-09-14 1 views
0

첨부 된 속성에서 BringIntoView를 사용하여 ListBox의 스크롤을 동기화하려고합니다.속성이 연결된 ListBoxItem에서 BringIntoView를 가져 오겠습니까?

내 시도가 작동하지 않습니다. 코드를 실행하면 선택한 항목이 목록 상자에 동기화됩니다. 그러나 다른 ListBox에 표시되지 않는 항목을 선택하면 자동으로 스크롤되지 않습니다.

저는 IsShown 및 ItemText 속성을 가진 간단한 ViewModel을 가지고 있습니다. 여기

<Window.Resources> 
    <Style TargetType="ListBoxItem"> 
     <Setter Property="IsSelected" Value="{Binding IsShown, Mode=TwoWay}"/> 
     <Setter Property="local:CustomProperties.BringIntoView" Value="{Binding IsShown}"/> 
    </Style> 
    <DataTemplate x:Key="DataTemplate1"> 
     <TextBlock Name="_txt" Text="{Binding ItemText}"/> 
    </DataTemplate> 
</Window.Resources> 
<Grid> 
    <Grid.ColumnDefinitions> 
     <ColumnDefinition Width="255*"/> 
     <ColumnDefinition Width="262*"/> 
    </Grid.ColumnDefinitions> 
    <ListBox ItemsSource="{Binding ItemList}" ItemTemplate="{StaticResource DataTemplate1}" /> 
    <ListBox Grid.Column="1" ItemsSource="{Binding ItemList}" ItemTemplate="{StaticResource DataTemplate1}" > 
    </ListBox>     
</Grid> 

내 종속성 속성

public static class CustomProperties 
{ 
    public static readonly DependencyProperty BringIntoViewProperty = 
     DependencyProperty.RegisterAttached("BringIntoView", 
     typeof(bool), 
     typeof(CustomProperties), 
     new PropertyMetadata(OnBringIntoViewChanged)); 

    public static void SetBringIntoView (DependencyObject o, bool value) 
    { 
     o.SetValue(BringIntoViewProperty, value); 
    } 

    public static bool GetBringIntoView (DependencyObject o) 
    { 

     return (bool)o.GetValue(BringIntoViewProperty); 
    } 

    private static void OnBringIntoViewChanged (DependencyObject d, DependencyPropertyChangedEventArgs e) 
    { 
     if ((bool)e.NewValue) 
     { 
      if (d is FrameworkElement) 
       ((FrameworkElement)d).BringIntoView(); 
     } 
    } 
} 

답변

0

어떻게 다른 접근 방법에 대한입니까?

항상 선택된 항목을 보려는 경우. ViewModel에서 ListCollectionView를 사용하는 경우 MoveCurrentTo() 및 기타 함수를 호출하여 선택을 변경할 수 있습니다. ListBox는이 ListCollectionView에 바인딩되며 기본적으로 IsSynchronizedWithCurrentItem 속성을 사용하여 선택한 항목을 동기화합니다.

이렇게하면 ViewModel이 현재 항목을 추적하고 ListBox가 바인딩됩니다.

private void listBox_SelectionChanged(object sender, SelectionChangedEventArgs e) 
{ 
    listBox.ScrollIntoView(listBox.SelectedItem); 
} 

귀하의 ViewModel 아마 필요가 없습니다 : 당신이보기에서 선택한 항목을 유지하기 위해 스크롤을 포함하도록 목록 상자의 동작을 원하는 경우

이제, 코드 숨김보기에 다음 코드를 추가합니다 이 세부 사항을 알기. 자동 스크롤은 뷰 동작의 일부일뿐입니다.

모든 것이 ViewModel에 있어야한다고 가정하는 것은 잘못된 것입니다. 예를 들어 텍스트 상자의 캐럿 위치는 신경 쓰지 않습니다. 나는 이것이 뷰 특정 (view-specific)의 것으로 자격이 있다고 생각한다.

+0

이것은 샘플 응용 프로그램에 불과합니다. 내 실제 프로젝트는 계층 적 데이터 및 목록 상자에 바인딩 된 데이터 병합 된 버전이있는 TreeView를 사용합니다. 모든 것을 처리하기 위해 하나의 콜렉션 뷰에 의존 할 수 있는지 확실하지 않습니다. – kbeal2k

관련 문제