0

我正在尝试在附加属性上使用 BringIntoView 同步我的 ListBox 的滚动。

我的尝试不起作用。当我运行我的代码时,所选项目会在列表框之间同步,但是如果我选择了一个未显示在另一个 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();
        }
    }
}
4

1 回答 1

0

不同的方法怎么样?

您希望始终显示所选项目。如果您在 ViewModel 中使用 ListCollectionView,您可以通过调用 MoveCurrentTo() 和其他函数来更改选择。您的 ListBox 将绑定到此 ListCollectionView,默认情况下将使用 IsSynchronizedWithCurrentItem 属性同步所选项目。

通过这种方式,您的 ViewModel 会跟踪当前项目,并且您的 ListBox 会绑定到它。

现在,如果您希望 ListBox 的行为包括滚动以使所选项目保持在视图中,请将以下代码添加到您的视图代码隐藏中:

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

你的 ViewModel 可能不需要知道这个细节。自动滚动只是视图行为的一部分。

假设一切都需要在您的 ViewModel 中可能是错误的。例如,我们不关心文本框中的插入符号位置。我认为这符合特定于视图的条件。

于 2012-09-14T20:47:32.433 回答