在 WPF 中运行时更改最近的文件子菜单内容

问题描述 投票:0回答:1

我尝试在我的应用程序中创建最近的文件子菜单。我的代码基于 https://www.itcodar.com/csharp/wpf-how-to-create-menu-and-submenus-using-binding.html

的示例

当我尝试以这样的方式使用静态菜单项时:

<MenuItem Header="_File">
    <MenuItem Header="_Open..." Command="Open"/>
    <MenuItem Header="_Save..." Command="Save"/>
    <Separator></Separator>
    <MenuItem Header="_Close" Command="Close"/>
    <Separator></Separator>
    <MenuItem Header="_Recent Files">
        <Menu  DockPanel.Dock="Top" ItemsSource="{Binding MenuItems}">
            <Menu.ItemContainerStyle>
                <Style TargetType="{x:Type MenuItem}">
                    <Setter Property="Command" Value="{Binding Command}" />
                </Style>
            </Menu.ItemContainerStyle>
            <Menu.ItemTemplate>
                <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}">
                    <TextBlock Text="{Binding Header }"/>
                </HierarchicalDataTemplate>
            </Menu.ItemTemplate>
        </Menu>
    </MenuItem>
</MenuItem>

通过单击此项目,我在打开的菜单左侧看到水平菜单,而不是垂直菜单。

我将此项目放置在动态菜单中:

<MenuItem Header="_File">
    <MenuItem Header="_Open..." Command="Open"/>
    <MenuItem Header="_Save..." Command="Save"/>
    <Separator></Separator>
    <MenuItem Header="_Close" Command="Close"/>
    <Separator></Separator>
    <Menu  DockPanel.Dock="Top" ItemsSource="{Binding MenuItems}">
        <Menu.ItemContainerStyle>
            <Style TargetType="{x:Type MenuItem}">
                <Setter Property="Command" Value="{Binding Command}" />
            </Style>
        </Menu.ItemContainerStyle>
        <Menu.ItemTemplate>
            <HierarchicalDataTemplate DataType="{x:Type local:MenuItemViewModel}" ItemsSource="{Binding Path=MenuItems}">
                <TextBlock Text="{Binding Header }"/>
            </HierarchicalDataTemplate>
        </Menu.ItemTemplate>
    </Menu>
</MenuItem>

我在打开的菜单下方有垂直子菜单。这不完全是我想要的,但可以接受。 但主要问题发生在我启动应用程序时 - 最近的文件列表未随新打开的文件更新。从申请开始起就保持不变。

所以我很有趣,如何在运行时更新动态菜单,并且作为障碍,如何将最近的文件列表放置在调用菜单的左侧?

wpf dynamic menu runtime
1个回答
0
投票

示例:

using Microsoft.Win32;
using Simplified;
using System.Collections.ObjectModel;
using System.IO;
using System.Windows;

namespace Core2023.SO.Old_Nick.question77731533
{
    public class FilesViewModel : ViewModelBase
    {
        public ObservableCollection<FileInfo> Files { get; } = new();

        public RelayCommand OpenFile => GetCommand(OpenFileExecute);
        public RelayCommand ReOpenFile => GetCommand<FileInfo>(OpenFileExecute);

        private void OpenFileExecute()
        {
            OpenFileDialog dialog = new OpenFileDialog();
            if (dialog.ShowDialog() == true)
                OpenFileExecute(new FileInfo(dialog.FileName));
        }
        private void OpenFileExecute(FileInfo fileInfo)
        {
            int index = Files.IndexOf(fileInfo);
            if (index < 0)
            {
                Files.Insert(0, fileInfo);
                while (Files.Count > 10)
                {
                    Files.RemoveAt(Files.Count - 1);
                }
            }
            else
            {
                Files.Move(index, 0);
            }

            MessageBox.Show($"Open File: {fileInfo.FullName}");
        }
    }
}
<Window x:Class="Core2023.SO.Old_Nick.question77731533.FilesWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Core2023.SO.Old_Nick.question77731533" xmlns:io="clr-namespace:System.IO;assembly=System.IO.FileSystem"
        mc:Ignorable="d"
        Title="FilesWindow" Height="450" Width="800"
        DataContext="{DynamicResource vm}">
    <Window.Resources>
        <local:FilesViewModel x:Key="vm"/>
    </Window.Resources>
    <Grid>
        <Menu>
            <MenuItem Header="File">
                <MenuItem Header="Open" Command="{Binding OpenFile}"/>
                <MenuItem Header="Recent Files" ItemsSource="{Binding Files}">
                    <MenuItem.ItemTemplate>
                        <DataTemplate DataType="{x:Type io:FileInfo}">
                            <Button Content="{Binding FullName}"
                                Command="{Binding ReOpenFile, Mode=OneWay, Source={StaticResource vm}}"
                                CommandParameter="{Binding}"/>
                        </DataTemplate>
                    </MenuItem.ItemTemplate>
                </MenuItem>
            </MenuItem>
        </Menu>
    </Grid>
</Window>
© www.soinside.com 2019 - 2024. All rights reserved.