0

我想做一个像 Windows Media Center 的音乐库界面一样的 WPF 菜单结构。基本上,前提是有一个类别和项目的列表。您可以使用左/右箭头键滚动类别。可用的类别“环绕”屏幕,列表中的第二项始终是选定的。该类别的可用项目位于类别下方的列表中。当您在类别中时,您可以按向下箭头导航到列表,这样做会导致上面的类别“删除”字体大小并淡出一点,并且列表项会弹出字体大小并淡出一点点。在项目列表中,您现在可以向左、向右、向上、向下导航项目。

我是一个完全的 WPF 菜鸟......任何指导将不胜感激。

最好的例子是尝试 WMC 音乐库界面——但是对于那些没有安装它的人,我提供了几个屏幕截图:

WMC 类别导航 WMC 项目导航

4

1 回答 1

2

我做了一些事情:

在此处输入图像描述

对于我采取元素TabControl的基础,通过你的截图他是最合适的。此外,它可能是 TabItem 任何控件(如DataGrid)。首先,您需要在 TabItem 中添加导航箭头(它代表一个类别)并需要它们隐藏未选中的 TabItem。要正确执行,需要在 TabItem (App.xaml) 的模板中执行:

    <Style x:Key="{x:Type TabItem}" TargetType="{x:Type TabItem}">
        <Setter Property="OverridesDefaultStyle" Value="True" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="Foreground" Value="Gray" />
        <Setter Property="BorderThickness" Value="0" />
        <Setter Property="BorderBrush" Value="Transparent" />
        <Setter Property="MinHeight" Value="20" />
        <Setter Property="MinWidth" Value="120" />
        <Setter Property="FontFamily" Value="./#Segoe UI" />
        <Setter Property="FontSize" Value="14" />
        <Setter Property="FontWeight" Value="Normal" />            
        <Setter Property="IsTabStop" Value="False" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type TabItem}">
                    <Border SnapsToDevicePixels="True" Name="Border" Margin="0,0,2,0" Background="{TemplateBinding Background}" BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0">
                        <Grid>
                            <!-- There are arrow Prev and Next -->
                            <Button Name="PrevButton" Style="{StaticResource PrevButton}" />
                            <ContentPresenter Name="ContentSite" HorizontalAlignment="Center" Margin="5" VerticalAlignment="Center" RecognizesAccessKey="True" ContentSource="Header" />
                            <Button Name="NextButton" Style="{StaticResource NextButton}" />
                        </Grid>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="TabStripPlacement" Value="Bottom">
                            <Setter TargetName="Border" Property="CornerRadius" Value="0" />
                        </Trigger>

                        <Trigger Property="TabStripPlacement" Value="Left">
                            <Setter TargetName="Border" Property="CornerRadius" Value="0" />
                        </Trigger>

                        <!-- Here is hiding the arrows -->
                        <Trigger Property="IsSelected" Value="False">
                            <Setter TargetName="PrevButton" Property="Visibility" Value="Collapsed" />
                            <Setter TargetName="NextButton" Property="Visibility" Value="Collapsed" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>

        <Style.Triggers>
            <Trigger Property="IsSelected" Value="True">
                <Setter Property="Background" Value="#F4F4F4" />
                <Setter Property="Foreground" Value="Black" />
                <Setter Property="FontSize" Value="16" />
            </Trigger>

            <Trigger Property="IsEnabled" Value="False">
                <Setter Property="Background" Value="Black" />
                <Setter Property="Foreground" Value="White" />
            </Trigger>
        </Style.Triggers>
    </Style>

箭头按钮 (App.xaml) 的样式:

    <!-- Prev button style -->
    <Style x:Key="PrevButton" TargetType="{x:Type Button}">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="HorizontalAlignment" Value="Left" />
        <Setter Property="Margin" Value="3,0,0,0" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="ToolTip" Value="Prev" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" Background="{TemplateBinding Background}">
                        <Grid>
                            <ContentPresenter RecognizesAccessKey="True" />
                            <Path x:Name="PrevButton" SnapsToDevicePixels="True" Width="13" Height="16" Stretch="Fill" Fill="Gray" Data="F1 M 35.8724,37.6042L 39.0391,40.7708L 50.5182,51.8542L 40.2266,51.8542L 25.1849,37.6041L 40.2266,23.3542L 50.5182,23.3542L 39.0391,34.4375L 35.8724,37.6042 Z " />
                        </Grid>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="PrevButton" Property="Fill" Value="Black" />
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="PrevButton" Property="Fill" Value="Green" />
                        </Trigger>

                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" Value="0.6" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

    <!-- Next button style -->
    <Style x:Key="NextButton" TargetType="{x:Type Button}">
        <Setter Property="Background" Value="Transparent" />
        <Setter Property="SnapsToDevicePixels" Value="True" />
        <Setter Property="HorizontalAlignment" Value="Right" />
        <Setter Property="Margin" Value="0,0,3,0" />
        <Setter Property="FocusVisualStyle" Value="{x:Null}" />
        <Setter Property="ToolTip" Value="Next" />

        <Setter Property="Template">
            <Setter.Value>
                <ControlTemplate TargetType="{x:Type Button}">
                    <Border BorderBrush="{TemplateBinding BorderBrush}" BorderThickness="{TemplateBinding BorderThickness}" CornerRadius="0" Background="{TemplateBinding Background}">
                        <Grid>
                            <ContentPresenter RecognizesAccessKey="True" />
                            <Path x:Name="NextButton" SnapsToDevicePixels="True" Width="13" Height="16" Stretch="Fill" Fill="Gray" Data="F1 M 39.8307,37.6042L 36.6641,34.4375L 25.1849,23.3542L 35.4766,23.3542L 50.5182,37.6042L 35.4766,51.8542L 25.1849,51.8542L 36.6641,40.7708L 39.8307,37.6042 Z " />
                        </Grid>
                    </Border>

                    <ControlTemplate.Triggers>
                        <Trigger Property="IsMouseOver" Value="True">
                            <Setter TargetName="NextButton" Property="Fill" Value="Black" />
                        </Trigger>

                        <Trigger Property="IsPressed" Value="True">
                            <Setter TargetName="NextButton" Property="Fill" Value="Green" />
                        </Trigger>

                        <Trigger Property="IsEnabled" Value="False">
                            <Setter Property="Opacity" Value="0.6" />
                        </Trigger>
                    </ControlTemplate.Triggers>
                </ControlTemplate>
            </Setter.Value>
        </Setter>
    </Style>

主窗口 XAML:

    <TabControl Name="SampleTabControl" HorizontalAlignment="Right" Loaded="TabControl_Loaded">
        <TabItem Name="Soccer" Header="Soccer">
            <ListBox Name="SoccerListBox" BorderBrush="Transparent" BorderThickness="0">
                <ListBoxItem>Player name: Ronaldo</ListBoxItem>
                <ListBoxItem>Player name: Messi</ListBoxItem>
                <ListBoxItem>Player name: Sergio Ramos</ListBoxItem>
                <ListBoxItem>Player name: Puyol</ListBoxItem>
            </ListBox>
        </TabItem>

        <TabItem Name="Hockey" Header="Hockey">
            <ListBox Name="HockeyListBox" BorderThickness="0">
                <ListBoxItem>Player name: Cal Heeter</ListBoxItem>
                <ListBoxItem>Player name: Jeff Petry</ListBoxItem>
                <ListBoxItem>Player name: Erik Johnson</ListBoxItem>
                <ListBoxItem>Player name: Matt Hunwick</ListBoxItem>
            </ListBox>
        </TabItem>

        <TabItem Name="Basketbol" Header="Basketbol">
            <ListBox Name="BasketbolListBox" BorderThickness="0">
                <ListBoxItem>Player name: Kobe Bryant</ListBoxItem>
                <ListBoxItem>Player name: Chris Paul</ListBoxItem>
                <ListBoxItem>Player name: Carmelo Anthony</ListBoxItem>
                <ListBoxItem>Player name: LeBron James</ListBoxItem>
            </ListBox>
        </TabItem>

        <TabItem Name="Baseball" Header="Baseball">
            <ListBox Name="BaseballListBox" BorderThickness="0">
                <ListBoxItem>Player name: Ralph Kiner</ListBoxItem>
                <ListBoxItem>Player name: Dizzy Dean</ListBoxItem>
                <ListBoxItem>Player name: Duke Snider</ListBoxItem>
                <ListBoxItem>Player name: Ozzie Smith</ListBoxItem>
            </ListBox>
        </TabItem>
    </TabControl>

现在你需要制作一个功能箭头工作者。为此,创建一个TabControl_Loaded事件,我们从模板中找到按钮,并将它们分配给事件处理程序:

    private void TabControl_Loaded(object sender, RoutedEventArgs e)
    {
        var items = SampleTabControl.Items;

        foreach (TabItem item in items)
        {
            Button MyPrevButton = (Button)item.Template.FindName("PrevButton", item);
            Button MyNextButton = (Button)item.Template.FindName("NextButton", item);

            MyPrevButton.Click += new RoutedEventHandler(MyPrevButton_Click);
            MyNextButton.Click += new RoutedEventHandler(MyNextButton_Click);
        }
    }

事件处理程序:

    private void MyPrevButton_Click(object sender, RoutedEventArgs e)
    {
        NavigationTabItem(SampleTabControl, "Prev", 1);
    }

    private void MyNextButton_Click(object sender, RoutedEventArgs e)
    {
        NavigationTabItem(SampleTabControl, "Next", 1);
    }

为了便于导航功能创建:

    private void NavigationTabItem(TabControl MyTabControl, string Direction, int Num) 
    {
        if (Direction == "Prev")
        {
            MyTabControl.SelectedIndex -= Num;
        }

        if (Direction == "Next")
        {
            MyTabControl.SelectedIndex += Num;
        }
    }

现在我们需要截取键盘接口。为此,创建了处理程序并将其安装在窗口上(最好将其安装在 TabControl 上,并在程序开始时将其置于焦点):

<Window ... KeyDown="SampleTabControl_KeyDown">

    private void SampleTabControl_KeyDown(object sender, KeyEventArgs e)
    {
        if (e.Key == Key.Down) 
        {
            if (SampleTabControl.SelectedIndex == 0)
            {
                SoccerListBox.Focus();
            }

            if (SampleTabControl.SelectedIndex == 1)
            {
                HockeyListBox.Focus();
            }

            if (SampleTabControl.SelectedIndex == 2)
            {
                BasketbolListBox.Focus();
            }

            if (SampleTabControl.SelectedIndex == 3)
            {
                BaseballListBox.Focus();
            }
        }

        if (e.Key == Key.Left)
        {
            NavigationTabItem(SampleTabControl, "Prev", 1);
        }

        if (e.Key == Key.Right)
        {
            NavigationTabItem(SampleTabControl, "Next", 1);
        }
    }

作为可选设置以选择 ListBoxItem 和 TabItem 上的动画。

于 2013-06-07T08:45:00.357 回答