WPF ListBox 사이클을 만들 수 있습니까? 즉, 상단과 하단에서 하드 스톱을 치지 않습니다

StackOverflow https://stackoverflow.com/questions/389341

문제

WPF Listbox가 데이터 객체에 바인딩되어 있습니다. Listbox 안에는 텍스트가있는 일련의 이미지가 있습니다. 그것은 수평 방식으로 배치되며 상자의 왼쪽 또는 오른쪽에 마우스를 뿌려 각각 왼쪽 또는 오른쪽 항목을 스크롤합니다.

ListBox에 20 개의 항목이 있다고 가정 해 봅시다. 나는 위치 19 항목 (0 기반)을 누르면 상자를 순환하고 컬렉션을 시작하여 1-19 등이 될 수있는 방법을 알아 내려고 노력하고 있습니다. 다른 방식으로 순환해야하므로 항목 0에 있고 왼쪽으로 스크롤하면 19가 얻을 수 있습니다.

KeyboardNavigation.DirectionAlnavigation = "Cycle"을 시도했지만, 나에게 아무것도하지 않는 것 같지 않으며, Keyboard와 아무 관련이 없기 때문에 빨대를 잡고있었습니다. 모든 마우스 기반입니다.

        <ListBox ItemsSource="{Binding Source={StaticResource WPFApparelCollection}}" Margin="24,-7,39,-19" ScrollViewer.VerticalScrollBarVisibility="Hidden" ScrollViewer.HorizontalScrollBarVisibility="Hidden" SelectionMode="Single" x:Name="list1" MouseLeave="List1_MouseLeave" MouseMove="List1_MouseMove" Style="{DynamicResource ListBoxStyle1}" Background="Transparent" BorderThickness="0">
            <ListBox.Resources>
                <!-- override the system brushes so that selected items are transparent whether the ListBox has focus or not -->
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightBrushKey}" Color="Transparent" />
                <SolidColorBrush x:Key="{x:Static SystemColors.ControlBrushKey}" Color="Transparent" />
                <SolidColorBrush x:Key="{x:Static SystemColors.HighlightTextBrushKey}" Color="Black" />
            </ListBox.Resources>
            <ListBox.ItemContainerStyle>
                <Style TargetType="{x:Type ListBoxItem}">
                    <Setter Property="Background" Value="Transparent" />
                    <Setter Property="HorizontalContentAlignment" Value="{Binding Path=HorizontalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                    <Setter Property="VerticalContentAlignment" Value="{Binding Path=VerticalContentAlignment, RelativeSource={RelativeSource AncestorType={x:Type ItemsControl}}}" />
                    <Setter Property="Padding" Value="20,10,20,10" />
                    <Setter Property="Template">
                        <Setter.Value>
                            <ControlTemplate TargetType="{x:Type ListBoxItem}">
                                <Border x:Name="Bd" SnapsToDevicePixels="true" Background="Transparent" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" Padding="{TemplateBinding Padding}">
                                    <ContentPresenter HorizontalAlignment="{TemplateBinding HorizontalContentAlignment}" VerticalAlignment="{TemplateBinding VerticalContentAlignment}" SnapsToDevicePixels="{TemplateBinding SnapsToDevicePixels}" />
                                </Border>
                                <ControlTemplate.Triggers>
                                    <Trigger Property="IsSelected" Value="true">
                                        <Setter Property="Background" TargetName="Bd" Value="Transparent" />
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.HighlightTextBrushKey}}" />
                                    </Trigger>
                                    <MultiTrigger>
                                        <MultiTrigger.Conditions>
                                            <Condition Property="IsSelected" Value="true" />
                                            <Condition Property="Selector.IsSelectionActive" Value="false" />
                                        </MultiTrigger.Conditions>
                                        <Setter Property="Background" TargetName="Bd" Value="{DynamicResource {x:Static SystemColors.ControlBrushKey}}" />
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.ControlTextBrushKey}}" />
                                    </MultiTrigger>
                                    <Trigger Property="IsEnabled" Value="false">
                                        <Setter Property="Foreground" Value="{DynamicResource {x:Static SystemColors.GrayTextBrushKey}}" />
                                    </Trigger>
                                </ControlTemplate.Triggers>
                            </ControlTemplate>
                        </Setter.Value>
                    </Setter>
                </Style>
            </ListBox.ItemContainerStyle>
            <ListBox.ItemsPanel>
                <ItemsPanelTemplate>
                    <VirtualizingStackPanel Orientation="Horizontal" IsItemsHost="True" />
                </ItemsPanelTemplate>
            </ListBox.ItemsPanel>
            <ListBox.ItemTemplate>
                <DataTemplate>
                    <StackPanel Orientation="Vertical">
                        <Image Source="{Binding Image}" MouseLeave="Image_MouseLeave" MouseEnter="Image_MouseEnter" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Image_MouseLeftButtonDown" VerticalAlignment="Top" HorizontalAlignment="Left"></Image>
                        <Label Content="{Binding Name}" Cursor="Hand" Tag="{Binding Link}" MouseLeftButtonDown="Label_MouseLeftButtonDown" VerticalAlignment="Bottom" Foreground="White" Style="{StaticResource Gotham-Medium}" FontSize="8pt" HorizontalAlignment="Center" />
                    </StackPanel>
                </DataTemplate>
            </ListBox.ItemTemplate>
        </ListBox>
도움이 되었습니까?

해결책

여기서 문제는 실제로는 아닙니다 리스트 박스, 그러나 스크롤 뷰어 제어 템플릿 내부; 따라서 항목주기를 만들려면 변경해야합니다. 스크롤 뷰어 어떤 식 으로든. 나는 파생 된 통제를 썼습니다 스크롤 뷰어 수직 방향으로 순환하지만 수평으로 작동하는 방법을 쉽게 알 수 있습니다.

public class CyclicScrollViewer : ScrollViewer
{
    public CyclicScrollViewer()
    {
        this.CommandBindings.Add(new CommandBinding(ScrollBar.LineUpCommand, LineCommandExecuted));
        this.CommandBindings.Add(new CommandBinding(ScrollBar.LineDownCommand, LineCommandExecuted));
    }

    private void LineCommandExecuted(object sender, ExecutedRoutedEventArgs e)
    {
        if (e.Command == ScrollBar.LineUpCommand)
        {
            if (this.VerticalOffset == 0)
                this.ScrollToEnd();
            else
                this.LineUp();
        }

        if (e.Command == ScrollBar.LineDownCommand)
        {
            if (this.VerticalOffset == this.ScrollableHeight)
                this.ScrollToTop();
            else
                this.LineDown();
        }
    }
}

그만큼 Scrollto ... 그리고 선... 메소드는 이미 존재합니다 스크롤 뷰어 코딩을 매우 간단하게 만듭니다. 내가 여기서하는 일은 스크롤하기 전에 뷰어의 한계에 대한 현재 오프셋을 확인하는 것입니다.

다음 단계는 새로운 것을 삽입하는 것입니다 스크롤 뷰어 대상 제어를위한 제어 템플릿으로,이 경우 리스트 박스. 다음은 XAML 스 니펫이 있습니다.

        <ControlTemplate x:Key="{x:Type ListBox}" TargetType="ListBox">
            ...
                <l:CyclicScrollViewer 
                    Padding="{TemplateBinding Control.Padding}" 
                    Focusable="False">
                    <ItemsPresenter ... />
                </l:CyclicScrollViewer>
            ...
        </ControlTemplate>

이 코드를 사용하는 샘플 응용 프로그램을 게시했습니다 여기. 이 샘플은 키보드 지원이 없지만 onkeydown 방법 및 적절한 실행 선... 명령. 이게 도움이 되길 바란다.

다른 팁

이를 수행하는 무료 및 상업용 WPF 회전식 구현이 많이 있습니다. 이 라운드 업을 살펴보십시오 http://mdavey.wordpress.com/2007/04/03/wpf-carousel/

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