简体   繁体   中英

Implementing an "About" menu item in WPF

It seems to be straightforward to get the Version Number eg

string ver Assembly.GetExecutingAssembly().GetName().Version.ToString();

And displaying that string in an "About..." menu item should also be. But Google results all seem complex eg

https://stackoverflow.com/questions/2849265/how-to-pass-data-when-using-menuitem-itemcontainerstyle

https://stackoverflow.com/questions/21585828/menuitem-passing-selected-item-to-viewmodel-via-relaycommand-ala-mvvm-light-he

There must be a simple way to do this. Something along the lines of

    Window x:Class="WpfApp1.MainWindow"
            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:WpfApp1"
            mc:Ignorable="d"
            Title="MainWindow" Height="350" Width="525">
        <Menu>
            <MenuItem Header="File">
                <MenuItem Header="Open"/>
                <MenuItem Header="Close"/>
            </MenuItem>
            <MenuItem Header="About">
                <MenuItem Header="Version"/>
            </MenuItem>
            <Grid>
            </Grid>
       </Menu>
    </Window>

where the last header becomes "Version" + ver.

Or moving into the more complex How do I dynamically bind and statically add MenuItems?

public partial class MainWindow : Window
{
    private ObservableCollection<MyObject> _windows = new ObservableCollection<MyObject>();

    public MainWindow()
    {
        InitializeComponent();
        Windows.Add(new MyObject { Title = "Collection Item 1" });
        Windows.Add(new MyObject { Title = "Collection Item 2" });
    }

    public ObservableCollection<MyObject> Windows
    {
        get { return _windows; }
        set { _windows = value; }
    }
}

public class MyObject
{
    public string Title { get; set; }
}

<Window x:Class="WpfApplication8.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        Title="MainWindow" Height="233" Width="143" Name="UI">
    <Window.Resources>
        <CollectionViewSource Source="{Binding ElementName=UI, Path=Windows}" x:Key="YourMenuItems"/>
     </Window.Resources>

    <Grid DataContext="{Binding ElementName=UI}">
        <Menu Height="24" VerticalAlignment="Top">
        <MenuItem Header="_View" >
                <MenuItem Header="Windows">
                    <MenuItem.ItemsSource>
                        <CompositeCollection>
                            <CollectionContainer Collection="{Binding Source={StaticResource YourMenuItems}}" />
                            <MenuItem Header="Menu Item 1" />
                            <MenuItem Header="Menu Item 2" />
                            <MenuItem Header="Menu Item 3" />
                        </CompositeCollection>
                    </MenuItem.ItemsSource>
                    <MenuItem.ItemContainerStyle>
                        <Style>
                            <Setter Property="MenuItem.Header" Value="{Binding Title}"/>
                        </Style>
                    </MenuItem.ItemContainerStyle>
                </MenuItem>
            </MenuItem>
        </Menu>
    </Grid>

(which doesn't display "Collection Item 1" etc for me)

Just for the record, here's an MWE which does the very simple thing I wanted.

using System.Collections.ObjectModel;
using System.Reflection;
using System.Windows;

namespace WpfApp2
{

    public partial class MainWindow : Window
    {
        public ObservableCollection<MyMenuItem> _windows = new ObservableCollection<MyMenuItem>();


        public MainWindow()
        {
            InitializeComponent();

            string ver = Assembly.GetExecutingAssembly().GetName().Version.ToString();
            MyMenuItem versionMenuItem = new MyMenuItem { Title = "Version " + ver };

            Windows.Add(versionMenuItem);
        }


        public ObservableCollection<MyMenuItem> Windows
        {
            get { return _windows; }
            set { _windows = value; }
        }
    }

    public class MyMenuItem
    {
        public string Title { get; set; }
    }
}


<Window x:Class="WpfApp2.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:local="clr-namespace:WpfApp2"
        Title="MainWindow" Height="233" Width="143" Name="UI">
    <Window.Resources>
        <CollectionViewSource Source="{Binding ElementName=UI, Path=Windows, FallbackValue=versionMenuItem, TargetNullValue=0}" x:Key="MyMenuItems" />
    </Window.Resources>

    <Grid DataContext="{Binding ElementName=UI}">
        <Menu Height="24" VerticalAlignment="Top">
            <MenuItem Header="_Version" >
                <MenuItem Header="About">
                    <MenuItem.ItemsSource>
                        <CompositeCollection>
                            <CollectionContainer Collection="{Binding Source={StaticResource MyMenuItems}}" />
                            <MenuItem Header="Licensed To" />
                        </CompositeCollection>
                    </MenuItem.ItemsSource >
                    <MenuItem.ItemContainerStyle>
                        <Style>
                            <Setter Property="MenuItem.Header" Value="{Binding Title}" />
                        </Style>
                    </MenuItem.ItemContainerStyle>
                </MenuItem>
            </MenuItem>
        </Menu>
    </Grid>
</Window>

<Application x:Class="WpfApp2.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             xmlns:local="clr-namespace:WpfApp2"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <Style TargetType="MenuItem">
            <Setter Property="HorizontalContentAlignment" Value="Left"/>
            <Setter Property="VerticalContentAlignment" Value="Center"/>
        </Style>
    </Application.Resources>
</Application>

Setting the FallbackValue to versionMenuItem to eliminate one of the Data issues.

<CollectionViewSource Source="{Binding ElementName=UI, Path=Windows, FallbackValue=versionMenuItem, TargetNullValue=0}" x:Key="MyMenuItems" />

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM