如何在MVVM中创建动态菜单

时间:2016-06-07 12:04:38

标签: xaml mvvm menu

我正在使用MVVM开发一个简单的WPF项目。

我想创建一个包含动态Items的菜单。

我的xaml文件:

<Menu.Resources>
    <Style TargetType="{x:Type MenuItem}">
        <Setter Property="Header"
                Value="{Binding MenuText}" />
        <Setter Property="Icon">
            <Setter.Value>
                <Image Source="{Binding MenuIcon}"
                       Height="16px"
                       Width="16px" />
            </Setter.Value>
        </Setter>

        <Setter Property="ItemsSource"
                Value="{Binding Children}" />

        <Setter Property="Command" Value="{Binding DataContext.ClickCommand , RelativeSource={RelativeSource Mode=FindAncestor, AncestorType=Menu}}"></Setter>
        <Setter Property="CommandParameter" Value="{Binding ItemCommandParameter}"></Setter>
    </Style>

</Menu.Resources>

这是视图模型类,它是我的xaml文件的内容:

private ObservableCollection<MenuItemModel> _topMenuItems;
public ObservableCollection<MenuItemModel> TopMenuItems
{
    get { return _topMenuItems; }
    set
    {
        if (_topMenuItems == value)
            return;

        Set("TopMenuItems", ref _topMenuItems, value);
    }
}

public void LoadMainMenu()
{
    IList<Model.MenuItemModel> fileMenuItems = PopulateFileMenuEntries();



    _topMenuItems = new ObservableCollection<MenuItemModel>();
    _topMenuItems.Add(new MenuItemModel() { MenuText = "_File", Children = new ObservableCollection<MenuItemModel>(fileMenuItems) });
}
IList<MenuItemModel> PopulateFileMenuEntries()
{
    List<MenuItemModel> fileMenuItems = new List<MenuItemModel>();

    fileMenuItems.Add(new MenuItemModel() { MenuText = "_Theme" });
    fileMenuItems.Add(new MenuItemModel() { MenuText = "_Exit" });

    return fileMenuItems;
}

我的菜单项型号类:

public class MenuItemModel : ObservableObject
{
    private string _menuText;
    public string MenuText
    {
        get { return _menuText; }
        set
        {
            if (_menuText == value)
                return;

            Set("MenuText", ref _menuText, value);
        }
    }


    private BitmapImage _menuIcon;
    public BitmapImage MenuIcon
    {
        get { return _menuIcon; }
        set
        {
            if (_menuIcon == value)
                return;

            Set("MenuIcon", ref _menuIcon, value);
        }
    }


    private ObservableCollection<MenuItemModel> _children;
    public ObservableCollection<MenuItemModel> Children
    {
        get { return _children; }
        set
        {
            Set("Children", ref _children, value);
        }
    }

    public string ItemCommandParameter { get; set; }
}

我的问题在这里:

如何动态填充菜单项而不是使用PopulateFileMenuEntries方法。例如,我想要一个List Collection,从数据库中获取正确的菜单项。如何将此列表集合分配给示例项目中的菜单项?我有2个带子项的菜单项:

主要:学生,老师,课程,...... 文件:主题,退出,......

1 个答案:

答案 0 :(得分:0)

我希望你能从中得到这个想法

  <Style TargetType="expanderControl:ExpanderControl">
    <Setter Property="HorizontalAlignment"
            Value="Stretch"/>
    <Setter Property="HorizontalContentAlignment" Value="Stretch"/>
    <Setter Property="ItemsPanel">
        <Setter.Value>
            <ItemsPanelTemplate>
                <StackPanel/>
            </ItemsPanelTemplate>
        </Setter.Value>
    </Setter>
    <Setter Property="Template">
        <Setter.Value>
            <ControlTemplate TargetType="expanderControl:ExpanderControl">
                <Grid>
                    <Grid.Resources>
                        <QuadraticEase x:Key="QuadraticEaseOut"
                                       EasingMode="EaseOut"/>
                        <QuadraticEase x:Key="QuadraticEaseInOut"
                                       EasingMode="EaseInOut"/>
                    </Grid.Resources>
                    <Grid.ColumnDefinitions>
                        <ColumnDefinition Width="41" />
                        <ColumnDefinition Width="*" />
                    </Grid.ColumnDefinitions>
                    <Grid.RowDefinitions>
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                        <RowDefinition Height="Auto" />
                    </Grid.RowDefinitions>
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="ExpansionStates">
                            <VisualStateGroup.Transitions>
                                <VisualTransition From="Collapsed"
                                                  GeneratedDuration="0:0:0.15"
                                                  To="Expanded">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                                       Storyboard.TargetName="ItemsCanvas"
                                                                       EnableDependentAnimation="True">
                                            <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseOut}"
                                                                  KeyTime="0:0:0.00"
                                                                  Value="0" />
                                            <EasingDoubleKeyFrame x:Name="CollapsedToExpandedKeyFrame"
                                                                  EasingFunction="{StaticResource QuadraticEaseOut}"
                                                                  KeyTime="0:0:0.15"
                                                                  Value="1" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimation Duration="0"
                                                         To="1.0"
                                                         Storyboard.TargetProperty="(UIElement.Opacity)"
                                                         Storyboard.TargetName="ItemsCanvas" />
                                    </Storyboard>
                                </VisualTransition>
                                <VisualTransition From="Expanded"
                                                  GeneratedDuration="0:0:0.15"
                                                  To="Collapsed">
                                    <Storyboard>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                                       Storyboard.TargetName="ItemsCanvas"
                                                                       EnableDependentAnimation="True">
                                            <EasingDoubleKeyFrame x:Name="ExpandedToCollapsedKeyFrame"
                                                                  EasingFunction="{StaticResource QuadraticEaseInOut}"
                                                                  KeyTime="0:0:0.00"
                                                                  Value="1" />
                                            <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}"
                                                                  KeyTime="0:0:0.15"
                                                                  Value="0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Opacity)"
                                                                       Storyboard.TargetName="ItemsCanvas">
                                            <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}"
                                                                  KeyTime="0:0:0.00"
                                                                  Value="1.0" />
                                            <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}"
                                                                  KeyTime="0:0:0.15"
                                                                  Value="0.0" />
                                        </DoubleAnimationUsingKeyFrames>
                                        <DoubleAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.RenderTransform).(CompositeTransform.TranslateY)"
                                                                       Storyboard.TargetName="ItemsCanvas"
                                                                       EnableDependentAnimation="True">
                                            <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}"
                                                                  KeyTime="0:0:0.00"
                                                                  Value="0.0" />
                                            <EasingDoubleKeyFrame EasingFunction="{StaticResource QuadraticEaseInOut}"
                                                                  KeyTime="0:0:0.15"
                                                                  Value="-35" />
                                        </DoubleAnimationUsingKeyFrames>
                                    </Storyboard>
                                </VisualTransition>
                            </VisualStateGroup.Transitions>
                            <VisualState x:Name="Collapsed">
                                <Storyboard>
                                    <DoubleAnimation Duration="0"
                                                     To="0"
                                                     Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                     Storyboard.TargetName="ItemsCanvas" />
                                    <DoubleAnimation Duration="0"
                                                     To="0.0"
                                                     Storyboard.TargetProperty="(UIElement.Opacity)"
                                                     Storyboard.TargetName="ItemsCanvas" />
                                </Storyboard>
                            </VisualState>
                            <VisualState x:Name="Expanded">
                                <Storyboard>
                                    <DoubleAnimation Duration="0"
                                                     Storyboard.TargetProperty="(FrameworkElement.Height)"
                                                     Storyboard.TargetName="ItemsCanvas" />
                                    <DoubleAnimation Duration="0"
                                                     To="1.0"
                                                     Storyboard.TargetProperty="(UIElement.Opacity)"
                                                     Storyboard.TargetName="ItemsCanvas" />
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                        <VisualStateGroup x:Name="ExpandabilityStates">
                            <VisualState x:Name="Expandable" />
                            <VisualState x:Name="NonExpandable">
                                <Storyboard>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                                   Storyboard.TargetName="ExpandableContent">
                                        <DiscreteObjectKeyFrame KeyTime="0:0:0.0"
                                                                Value="Collapsed" />
                                    </ObjectAnimationUsingKeyFrames>
                                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="(UIElement.Visibility)"
                                                                   Storyboard.TargetName="NonExpandableContent">
                                        <DiscreteObjectKeyFrame KeyTime="0:0:0.0"
                                                                Value="Visible" />
                                    </ObjectAnimationUsingKeyFrames>
                                </Storyboard>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <ListViewItem x:Name="ExpandableContent" Background="Transparent" 
                                  Grid.ColumnSpan="2"
                                  Grid.Column="0"
                                  Grid.Row="0"
                                  Grid.RowSpan="2" >
                        <Grid>
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="41" />
                                <ColumnDefinition Width="*" />
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                                <RowDefinition Height="Auto" />
                            </Grid.RowDefinitions>
                            <ContentControl x:Name="Header"
                                            Grid.ColumnSpan="2"
                                            ContentTemplate="{TemplateBinding HeaderTemplate}"
                                            Content="{TemplateBinding Header}"
                                            Grid.Column="0"
                                            HorizontalAlignment="Stretch"
                                            HorizontalContentAlignment="Stretch"
                                            Grid.Row="0" />
                            <ContentControl x:Name="Expander"
                                            ContentTemplate="{TemplateBinding ExpanderTemplate}"
                                            Content="{TemplateBinding Expander}"
                                            Grid.Column="1"
                                            HorizontalAlignment="Stretch"
                                            HorizontalContentAlignment="Stretch"
                                            Margin="11,0,0,0"
                                            Grid.Row="1" />
                            <Grid x:Name="ExpanderPanel"
                                  Background="Transparent"
                                  Grid.ColumnSpan="2"
                                  Grid.Column="0"
                                  Grid.Row="0"
                                  Grid.RowSpan="2"
                                  />
                            <StackPanel Height="1" Background="Black" Grid.ColumnSpan="2"
                                  Grid.Column="0"
                                  Grid.Row="0"
                                  Grid.RowSpan="2" VerticalAlignment="Bottom"></StackPanel>
                        </Grid>
                    </ListViewItem>
                    <ContentControl x:Name="NonExpandableContent"
                                    Grid.ColumnSpan="2"
                                    ContentTemplate="{TemplateBinding NonExpandableHeaderTemplate}"
                                    Content="{TemplateBinding NonExpandableHeader}"
                                    Grid.Column="0"
                                    HorizontalAlignment="Stretch"
                                    HorizontalContentAlignment="Stretch"
                                    Grid.Row="0"
                                    Grid.RowSpan="2"
                                    Visibility="Collapsed" />
                    <Canvas x:Name="ItemsCanvas"
                            Grid.Column="1"
                            Margin="-120,0,0,0"
                            Opacity="0.0"
                            Grid.Row="2"
                            Width="{Binding ActualWidth, ElementName=Presenter}"
                            Height="{Binding ActualHeight, ElementName=Presenter}">
                        <Canvas.RenderTransform>
                            <CompositeTransform TranslateY="0.0" />
                        </Canvas.RenderTransform>
                        <ItemsPresenter x:Name="Presenter" />
                    </Canvas>
                </Grid>
            </ControlTemplate>
        </Setter.Value>
    </Setter>
</Style>