ツリー・データ・バインディングやメニュースタイルWPF

序文

WPFの開発では、多くの場合、メニューとContentMenuに使用。しかし、非常に非友好的な人々のためのより良いインターフェイスのための比較的単純な、比較的追求のネイティブスタイル。変更メニューのスタイルに関連するので、。同時に、我々はまた、データが自動的にMenuItemのアイテムを起動すると、メニュー自動データモデルのビューにバインドしたいです。その後、我々は、これらのアイデアの簡単な実装を行います。

ビューモデル

私たちは、メニュー項目がテキストで説明してサムネイルを表示する必要があるの意図されていることを前提としています。そこに画像パスの名前と属性を持っている必要があり、私たちはそう。ツリーデータを形成するために、サブキー子供のセットを格納するために必要な、追加。

ビューモデルクラス

public class CommonTreeModel
{
    /// <summary>
    /// 名字
    /// </summary>
    public string Name { get; set; }
    /// <summary>
    /// 图片的路径
    /// </summary>
    public string IconPath { get; set; }
    /// <summary>
    /// 子项
    /// </summary>
    public ObservableCollection<CommonTreeModel> Children { get; set; }
}

データモック

私たちは、使用されBogusたシミュレーションデータを生成しました。使用して、に偽のアドオンを検索nuget。

/// <summary>
/// 菜单项数据集,前端将binding到该属性上
/// </summary>
public ObservableCollection<CommonTreeModel> MenuTreeSource { get; set; }

private void InitData()
{
    var general = new Bogus.Faker<CommonTreeModel>()
        .RuleFor(t => t.Name, t => t.Commerce.Product())//名字:商业产品
        .RuleFor(t => t.IconPath, t => t.Image.LoremFlickrUrl(32, 32));//图片:使用LoremFlick网站的图片
    var rd = new Random(DateTime.Now.Millisecond);//随机数
    MenuTreeSource = GenerateTreeData(general, rd, 10, 3, 10);
}

private ObservableCollection<CommonTreeModel> GenerateTreeData(Faker<CommonTreeModel> faker, Random rd, int topCount, int subMin, int subMaxm, int level = 0, int levelLimit = 4)
{
    var list = new ObservableCollection<CommonTreeModel>(faker.Generate(level == 0 ? topCount : rd.Next(subMin, subMaxm)));
    level++;
    if (level < levelLimit)
    {
        foreach (var item in list)
        {
            if (rd.Next() % 2 == 0)
            {
                item.Children = GenerateTreeData(faker, rd, topCount, subMin, subMaxm, level, levelLimit);
            }
        }
    }
    return list;
}

ここでは、ツリー4として可能な最大レベルを生成しますMenuTreeSource

WPFメニューで

データにバインドレッツ・ライト・フロントエンドメニュー。

<Menu ItemsSource="{Binding MenuTreeSource}" HorizontalAlignment="Center">
    <Menu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}">
            <Label Content="{Binding Name}"></Label>
        </HierarchicalDataTemplate>
    </Menu.ItemTemplate>
</Menu>

元の表示以下の効果、4の合計と、第一段階のスタイルと3つの矛盾しました。

私達はちょうどメニューの効果を示すように変更することができ、MenuItemのスタイルを書き換える必要があります。

<Style TargetType="MenuItem">
    <Setter Property="FontSize" Value="20"></Setter>
    <Setter Property="Foreground" Value="#b8d00a"></Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate>
                <Grid>
                    <Grid.Style>
                        <Style TargetType="Grid">
                            <Setter Property="Background" Value="#b8d00a"/>
                            <Style.Triggers>
                                <Trigger Property="IsMouseOver" Value="True">
                                    <Setter Property="Background" Value="#f46a56"></Setter>
                                </Trigger>
                            </Style.Triggers>
                        </Style>
                    </Grid.Style>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="auto"></ColumnDefinition>
                        <ColumnDefinition Width="*"></ColumnDefinition>
                        <ColumnDefinition Width="auto"></ColumnDefinition>
                    </Grid.ColumnDefinitions>
                    <Image Width="32" Height="32" Margin="5" Source="{Binding IconPath}" />
                    <Label Content="{Binding Name}" Margin="10 0" Grid.Column="1" VerticalContentAlignment="Center"/>
                    <Label Name="MoreLbl" Content=">>" Grid.Column="2" VerticalContentAlignment="Center">
                        <Label.Style>
                            <Style TargetType="Label">
                                <Setter Property="Visibility" Value="Visible"></Setter>
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Children}" Value="{x:Null}">
                                        <Setter Property="Visibility" Value="Collapsed"></Setter>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Label.Style>
                    </Label>
                    <Popup AllowsTransparency="True"
                        IsOpen="{Binding Path=IsSubmenuOpen, RelativeSource={RelativeSource TemplatedParent}}"
                        Placement="Right" x:Name="SubMenuPopup" Focusable="false">
                        <Border x:Name="SubMenuBorder"  BorderThickness="1" BorderBrush="Black">
                            <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
                        </Border>
                    </Popup>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

コントロールは、Popup子メニュー項目の代表的なものです。これでは保証は適切な子供を扱います。StackPanelIsItemsHost="True"

呼び出されMoreLbl Labelコントロールは、子供を持っているかどうかをプロンプトに使用されています。>>ここにアイデンティティを簡単にする表情で、読者はイメージパス制御を画像や美しいスタイルを作ることができます。

次のように最終的な結果は、一次と二次的なものであるが、まだ統一しない、です。

メニュープライマリとセカンダリの統一

団結のために我々は、メニューのスタイルに調整する必要があります。最も簡単な方法は、我々は、容器交換サブアイテムを運ぶことでStackPanel制御し、垂直方向に設定した内容を並べ替えます。

<Menu ItemsSource="{Binding MenuTreeSource}" HorizontalAlignment="Center">
    <Menu.ItemsPanel>
        <ItemsPanelTemplate>
            <StackPanel Orientation="Vertical"></StackPanel>
        </ItemsPanelTemplate>
    </Menu.ItemsPanel>
    <Menu.ItemTemplate>
        <HierarchicalDataTemplate ItemsSource="{Binding Children}"></HierarchicalDataTemplate>
    </Menu.ItemTemplate>
</Menu>

次のように最終的な結果は以下のとおりです。

WPFコントロールでのContextMenu

メニューとのContextMenuの異なる、彼はそのようなリストボックス、ラベル、グリッドやメニューの他のコンテンツとして、ポップアップメニューコントロールのポップアップ多くの形態を、右クリックすることができますよう私たちは、あなたがそれを取り出すことができ、マウスの右ボタンを必要とする、可能です。

私たちは、使うLabel簡単な例を:

<Label Content="鼠标右键弹出ContextMenu" HorizontalAlignment="Center"HorizontalContentAlignment="Center" FontSize="25" Background="#221a12"Foreground="#b8d00a"
     MouseDown="Label_MouseDown">
    <Label.ContextMenu>
        <ContextMenu ItemsSource="{Binding MenuTreeSource}">
            <ContextMenu.ItemTemplate>
                <HierarchicalDataTemplate ItemsSource="{Binding Children}" />
            </ContextMenu.ItemTemplate>
        </ContextMenu>
    </Label.ContextMenu>
</Label>

スタイルはグローバルスタイルがある前に、それは自動的にデフォルトを使用します。結果は以下の通りであります:

スタイルを見つけることができるが、わずかに異なっている、我々は変更する必要があるContextMenuスタイルを

<Style TargetType="{x:Type ContextMenu}">
    <Setter Property="SnapsToDevicePixels" Value="True"/>
    <Setter Property="OverridesDefaultStyle" Value="True"/>
    <Setter Property="Grid.IsSharedSizeScope" Value="true"/>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="{x:Type ContextMenu}">
                <Border 
                    BorderBrush="Black"
                    BorderThickness="1" >
                    <StackPanel IsItemsHost="True" KeyboardNavigation.DirectionalNavigation="Cycle"/>
                </Border>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>

単純なテンプレートを書き換えることができます。

概要

ここでは、メニューの表示効果を変更するためにスタイルテンプレートを書き換える方法についてのみの簡単な紹介。特に、私たちはより良いに見える結果を使用する必要があり、自分自身を設計してください。WPFプロジェクトの枠組みの用途はcore3.1バージョンをDOTNET。farmworkでは同じである必要があります。

おすすめ

転載: www.cnblogs.com/hsxian/p/12521501.html