首页 > 解决方案 > 在菜单中显示对话框并防止单击对话框控件关闭菜单/对话框

问题描述

我有一个菜单项。当我单击该项目时,我希望子菜单项打开并显示一个登录表单。

下面是我已经制作的(随意完全重新设计)......现在的问题是:

谢谢您的帮助!

<MenuItem>
            <MenuItem.Header>
                <Image
                    Width="16"
                    Height="16">
                    <Image.Style>
                        <Style TargetType="{x:Type Image}">
                            <Setter Property="Source" Value="{StaticResource DisconnectedIcon}" />
                            <Style.Triggers>
                                <DataTrigger Value="True" Binding="{Binding Connected}">
                                    <Setter Property="Source" Value="{StaticResource ConnectedIcon}"/>
                                </DataTrigger>
                            </Style.Triggers>
                        </Style>
                    </Image.Style>
                </Image>
            </MenuItem.Header>
            <autogrid:AutoGrid
                Columns="Auto,Auto"
                Margin="1"
                RowHeight="25">
                <autogrid:AutoGrid.Resources>
                    <Style TargetType="{x:Type TextBox}">
                        <Setter Property="Margin" Value="3" />
                        <Setter Property="Width" Value="100" />
                    </Style>
                    <Style TargetType="{x:Type PasswordBox}">
                        <Setter Property="Margin" Value="3" />
                        <Setter Property="Width" Value="100" />
                    </Style>
                    <Style TargetType="{x:Type TextBlock}">
                        <Setter Property="Margin" Value="3" />
                        <Setter Property="Width" Value="100" />
                    </Style>
                </autogrid:AutoGrid.Resources>
                <TextBlock Text="System: "/>
                <TextBox></TextBox>
                <TextBlock Text="Username: "/>
                <TextBox></TextBox>
                <TextBlock Text="Password: "/>
                <PasswordBox></PasswordBox>
            </autogrid:AutoGrid>
            <Button Content="Connect"/>
        </MenuItem>

标签: c#wpf

解决方案


我建议让您的登录控件成为新窗口的一部分。

对于其他跟随者,您需要Install-Package WpfAutoGrid -Version 1.4.0在包管理器控制台中运行。

以供将来参考,请发布一个最小且完整的示例。我花了比应该把它放在一起的时间更长的时间。

请阅读“如何创建最小、完整且可验证的示例”

这是我的 MCVE 示例:

连接

断开

MainWindow.xaml:

<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:autogrid="clr-namespace:WpfAutoGrid;assembly=WpfAutoGrid"
        xmlns:local="clr-namespace:WpfApp1"
        mc:Ignorable="d"
        Title="MainWindow" Height="250" Width="500">
    <Window.DataContext>
        <local:VM/>
    </Window.DataContext>
    <DockPanel>
        <Menu DockPanel.Dock="Top">
            <MenuItem>
                <MenuItem.Header>
                    <Image
                    Width="16"
                    Height="16">
                        <Image.Style>
                            <Style TargetType="{x:Type Image}">
                                <Setter Property="Source" Value="{StaticResource DisconnectedIcon}" />
                                <Style.Triggers>
                                    <DataTrigger Binding="{Binding Connected}" Value="true">
                                        <Setter Property="Source" Value="{StaticResource ConnectedIcon}"/>
                                    </DataTrigger>
                                    <DataTrigger Binding="{Binding Connected}" Value="false">
                                        <Setter Property="Source" Value="{StaticResource DisconnectedIcon}"/>
                                    </DataTrigger>
                                </Style.Triggers>
                            </Style>
                        </Image.Style>
                    </Image>
                </MenuItem.Header>
                <MenuItem x:Name="connectMenuItem" Header="{Binding ConnectOrDisconnect}" Click="MenuItem_Click"/>
            </MenuItem>
        </Menu>
        <Grid DockPanel.Dock="Bottom" Background="Black" />
    </DockPanel>
</Window>

MainWindow.xaml.cs:

using System.Windows;

namespace WpfApp1
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
        }

        private void MenuItem_Click(object sender, RoutedEventArgs e)
        {
            VM thisDC = (VM)this.DataContext;
            if (thisDC.Connected)
            {
                // DisConnect
                thisDC.Connected = false;
            }
            else
            {
                ConnectWindow cw = new ConnectWindow
                {
                    Owner = this,
                    DataContext = this.DataContext
                };
                cw.ShowDialog();
            }
        }
    }
}

ConnectWindow.xaml:

<Window x:Class="WpfApp1.ConnectWindow"
        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:autogrid="clr-namespace:WpfAutoGrid;assembly=WpfAutoGrid"
        mc:Ignorable="d" Title="ConnectWindow" Height="180" Width="270">
    <autogrid:AutoGrid            
                    Columns="Auto,Auto"
                    Rows="Auto,Auto, Auto, Auto"
                    Margin="20"
                    RowHeight="25">
        <autogrid:AutoGrid.Resources>
            <Style TargetType="{x:Type TextBox}">
                <Setter Property="Margin" Value="3" />
                <Setter Property="Width" Value="100" />
            </Style>
            <Style TargetType="{x:Type PasswordBox}">
                <Setter Property="Margin" Value="3" />
                <Setter Property="Width" Value="100" />
            </Style>
            <Style TargetType="{x:Type TextBlock}">
                <Setter Property="Margin" Value="3" />
                <Setter Property="Width" Value="100" />
            </Style>
        </autogrid:AutoGrid.Resources>
        <TextBlock Text="System: "/>
        <TextBox></TextBox>
        <TextBlock Text="User Name: "/>
        <TextBox></TextBox>
        <TextBlock Text="Password: "/>
        <PasswordBox></PasswordBox>
        <Button Grid.ColumnSpan="2" Content="Connect" Click="Button_Click" />
    </autogrid:AutoGrid>
</Window>

ConnectWindow.xaml.cs:

using System.Windows;

namespace WpfApp1
{
    public partial class ConnectWindow : Window
    {
        public ConnectWindow()
        {
            InitializeComponent();
        }

        private bool verified = true;

        private void Button_Click(object sender, RoutedEventArgs e)
        {
            if (verified)
            {
                VM thisDC = (VM)this.DataContext;
                thisDC.Connected = true;
                this.Close();
            }
            else
            {
                // error message
                this.Close();
            }
        }
    }
}

虚拟机.cs:

using System.ComponentModel;

namespace WpfApp1
{
    class VM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        private bool connected; 
        public bool Connected
        {
            get { return connected; }
            set
            {
                {
                    connected = value;
                    OnPropertyChanged("Connected");
                    if (value) { ConnectOrDisconnect = "Disconnect"; }
                    else { ConnectOrDisconnect = "Connect"; }
                }
            }
        }

        private string connectOrDisconnect;
        public string ConnectOrDisconnect
        {
            get { return connectOrDisconnect; }
            set
            {
                connectOrDisconnect = value;
                OnPropertyChanged("ConnectOrDisconnect");
            }
        }

        public VM()
        {
            Connected = false;
        }

        protected void OnPropertyChanged(string name)
        {
            PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(name));
        }
    }
}

应用程序.xaml:

<Application x:Class="WpfApp1.App"
             xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
             StartupUri="MainWindow.xaml">
    <Application.Resources>
        <ResourceDictionary>
            <ResourceDictionary.MergedDictionaries>
                <ResourceDictionary Source="resources.xaml"/>
            </ResourceDictionary.MergedDictionaries>
        </ResourceDictionary>
    </Application.Resources>
</Application>

资源.xaml:

<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
                    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
    <BitmapImage x:Key="ConnectedIcon" UriSource="pack://application:,,,/WpfApp1;component/ConnectedIcon.ico" />
    <BitmapImage x:Key="DisconnectedIcon" UriSource="pack://application:,,,/WpfApp1;component/DisconnectedIcon.ico" />
</ResourceDictionary>

推荐阅读