65.9K
CodeProject 正在变化。 阅读更多。
Home

WPF 中的简单 WP7 JumpList

starIconstarIconstarIconstarIcon
emptyStarIcon
starIcon

4.81/5 (12投票s)

2011 年 5 月 22 日

CPOL

3分钟阅读

viewsIcon

42361

downloadIcon

852

在 WPF 中重新创建 Windows Phone 7 JumpList

引言

我对 Microsoft 创造的基于排版的 Metro UI 设计印象深刻。它非常简洁快速。在本文中,我将演示如何在 WPF 中创建一个简单的 WP7 JumpList 示例。WP7 JumpList 在 MIX '11 活动中进行了演示。

WP7 JumpList Image

Using the Code

WPF JumpList 控件由两个控件组成

  • IndexControl - 用于显示索引。
  • JumpListControl - 封装 JumpList 的内容。

IndexControl

IndexControl 用于在 ValuesPanelJumpListPanel 中显示索引。它有一个依赖属性 IndexValue,用于在 IndexControl 中显示索引值。

public static readonly DependencyProperty IndexValueProperty =
    DependencyProperty.Register("IndexValue", typeof(string), typeof(IndexControl),
        new FrameworkPropertyMetadata
        ((new PropertyChangedCallback(OnIndexValueChanged))));

IndexControl 还有一个依赖属性 IndexState 来定义其状态。

public static readonly DependencyProperty IndexStateProperty =
    DependencyProperty.Register("IndexState", 
    typeof(IndexStateType), typeof(IndexControl),
    new FrameworkPropertyMetadata(IndexStateType.ListDisplay, 
    (new PropertyChangedCallback(OnIndexStateChanged))));

共有三种状态,由 enum IndexStateType 定义。

public enum IndexStateType
{
    // The state when the IndexControl is displayed in the long list.
    ListDisplay,
    // The state when the IndexControl is displayed in the JumpList 
    // and this index has NO values
    IndexNotFound,
    // The state when the IndexControl is displayed in the JumpList 
    // and this index has values
    IndexFound
}

根据其状态,IndexControl 的外观会发生变化。

IndexState Types

JumpListControl

WPF JumpList 控件有两个面板

  • ValuesPanel - 用于以长列表格式显示值(名称)。
  • JumpListPanel - 用于显示索引。

在任何给定实例中,上述面板中只有一个在 JumpListControl 中可见,而另一个面板保持隐藏状态。

ValuesPanel

WPF JumpList Image

ValuesPanel 以长列表格式显示值(或名称)。对于每个索引,IndexControl 和一组名称都封装在一个 StackPanel 中,并添加到父 StackPanel

Values Panel Image

JumpListPanel

WPF JumpList Image

JumpListPanel 由一个 WrapPanel 组成,其中添加了 IndexControls

JumpList Panel Image

JumpListPanel 定义了两个依赖属性

  • Values - ObservableCollection<string> - 用作控件的输入。
    public static readonly DependencyProperty ValuesProperty =
        DependencyProperty.Register("Values", 
        typeof(ObservableCollection<string>), typeof(JumpListControl),
        new FrameworkPropertyMetadata
        ((new PropertyChangedCallback(OnValuesChanged))));
  • SelectedValue - 指示用户选择的值(或名称)。
    public static readonly DependencyProperty SelectedValueProperty =
        DependencyProperty.Register("SelectedValue", 
        typeof(string), typeof(JumpListControl),
        new FrameworkPropertyMetadata
        ((new PropertyChangedCallback(OnSelectedValueChanged))));

JumpListControl 被初始化时,它会将 IndexControls 添加到 JumpListPanel,用于索引 a-z。每个 IndexControl 的状态设置为 IndexNotFound

public JumpListControl()
{
    InitializeComponent();

    JumpListScrollView.Visibility = System.Windows.Visibility.Hidden;

    foreach (char idx in indexes)
    {
        IndexControl idxCtrl = new IndexControl
        {
            Width = 50,
            Height = 50,
            IndexValue = idx.ToString(),
            IndexState = IndexStateType.IndexNotFound,
            Margin = new Thickness(4, 4, 0, 0)
        };

        idxCtrl.MouseLeftButtonDown += 
            new MouseButtonEventHandler(OnIndexClickedInJumpList);

        JumpListPanel.Children.Add(idxCtrl);
    }
}

当用户设置 Values 依赖属性时,JumpListControl 会解析列表并在 ValuesPanel 中创建索引长列表,并将 JumpListPanel 中的 IndexControls 的状态从 IndexNotFound 更改为 IndexFound

private void Parse(ObservableCollection<string> values)
{
    Dictionary<string, List<string>> valueDict = new Dictionary<string, List<string>>();

    List<string> valueList = values.ToList();

    // Sort the values
    valueList.Sort();

    // Get the distinct indexes
    foreach (string str in valueList)
    {
        string key = Char.ToLower(str[0]).ToString();
        if (!valueDict.ContainsKey(key))
        {
            valueDict[key] = new List<string>();
        }
        valueDict[key].Add(str);
    }

    // Set the IndexState of all the IndexControls 
    // whose index has been found as IndexFound
    JumpListPanel.Children.OfType<IndexControl>()
                          .Where(i => valueDict.Keys.Contains(i.IndexValue))
                          .All(i =>
                          {
                              i.IndexState = IndexStateType.IndexFound;
                              return true;
                          });


    // Add the index and the related names to the Values Panel
    foreach (string key in valueDict.Keys)
    {
        StackPanel stkPanel = new StackPanel 
	{ HorizontalAlignment = System.Windows.HorizontalAlignment.Stretch };

        IndexControl idxCtrl = new IndexControl
        {
            Width = 50,
            Height = 50,
            IndexValue = key,
            IndexState = IndexStateType.ListDisplay,
            Margin = new Thickness(4),
            HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
            VerticalAlignment = System.Windows.VerticalAlignment.Center
        };

        idxCtrl.MouseLeftButtonDown += 
		new MouseButtonEventHandler(OnIndexClickedInValuesPanel);

        stkPanel.Children.Add(idxCtrl);

        foreach (string str in valueDict[key])
        {
            TextBlock tb = new TextBlock
            {
                FontFamily = font,
                FontWeight = FontWeights.Light,
                FontSize = 22,
                Foreground = Brushes.White,
                TextAlignment = TextAlignment.Left,
                Margin = new Thickness(4, 4, 0, 0),
                Text = str,
                HorizontalAlignment = System.Windows.HorizontalAlignment.Left,
                VerticalAlignment = System.Windows.VerticalAlignment.Center
            };

            tb.MouseLeftButtonDown += new MouseButtonEventHandler(OnValueSelected);

            stkPanel.Children.Add(tb);
        }

        ValuesPanel.Children.Add(stkPanel);
    }
}

ValuesPanel 正在显示且用户单击任何索引时,ValuesPanel 将被隐藏,JumpListPanel 将被显示。当用户单击 JumpListPanel 中的任何索引时,JumpListPanel 将被隐藏,ValuesPanel 将被显示,并且 ValuePanel 滚动到用户选择的索引。

单击任何名称将设置 JumpListControlSelectedValue 属性。

端点

我在这里尝试的是 JumpList 控件的基本实现,它接受一个 string 列表作为输入。它可以进一步修改以接受 object 集合(例如一个人的记录),并且可以在 ValuesPanel 中每个名称旁边显示一张图片。

关注点

我在开发此控件期间学到的一个重要教训是,当您将项目添加到 WrapPanel(例如,使用 Orientation=Horizontal)并且项目超出 WrapPanel 的高度时,则垂直滚动条不会自动出现(即使您设置了 ScrollViewer.VerticalScrollBarVisibility="Auto")。

要克服这个问题,您需要用 ScrollViewer 包装您的 WrapPanel

<ScrollViewer Name="JumpListScrollView"
              HorizontalScrollBarVisibility="Disabled"
              VerticalScrollBarVisibility="Auto">
    <WrapPanel Name="JumpListPanel"
               Orientation="Horizontal">
    </WrapPanel>
</ScrollViewer>

历史

  • 2010 年 5 月 22 日 - 版本 1.0 发布
© . All rights reserved.