我是WPF的新手并一直在寻找答案,当然这并不困难?
我创建了一个主窗口,其中包含指向多个窗口的链接,我希望它们可以无模式地并排运行,但我不想打开SAME窗口的多个实例。
简单来说,我可以同时打开Windows A,B,C,但不能打开Windows,A,A,B,C,C。
我需要对我正在尝试打开的窗口执行检查(在本例中为EditSettings)。
如果打开 - 激活它
如果没有打开,请打开它。
我在Main中有以下代码,但无效。
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
}
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
EditSettings winEditSettings = new EditSettings();
string isOpen = null;
if (isOpen == "true")
{
winEditSettings.Activate();
}
else
{
winEditSettings.Show();
isOpen = "true";
}
}
}
现在我知道这个逻辑有什么问题 - 每次按下按钮打开EditSettings,它的设置isOpen再次为null。如果我没有为isOpen设置值,则If条件会中断。
我可以将变量'isOpen'初始化为MenuItem_Click方法之外的公共变量,但是我认为我需要为我创建的每个窗口创建一个isOpen变量!当然有更好的方法吗?
我尝试的另一个选项是:
private void MenuItem_Click(object sender, RoutedEventArgs e)
{
EditSettings winEditSettings = new EditSettings();
if (winEditSettings.IsLoaded)
{
winEditSettings.Activate();
}
else { winEditSettings.Show(); }
我无法弄清楚为什么这不起作用,我试过isVisible,isLoaded,isActive - 没有什么能阻止窗口不止一次打开。感谢您的帮助!
答案 0 :(得分:1)
有些人可能会对这个想法有所帮助,但每当我需要这样做时,我都会将子窗口对象作为应用程序的一部分。然后,在MenuItem_Click()
中,测试winEditSettings
是否为null
,而不是。{/ p>
它仍然是每个窗口的成员变量(就像您的临时isOpen
解决方案一样),但如果您需要在窗口之间桥接信息,那么将窗口对象提供后可能会有优势。在我的情况下,我们希望能够将所有子窗口关闭在一起,这些(最简单的)意味着在中心位置跟踪这些对象。
或者,如果您希望设置完全解耦,您可以采用类似单一的方法并将逻辑放入子窗口类中。具体来说,您可以调用EditSettings.Activate
并让班级跟踪是否需要创建窗口或现有窗口Show()
n。
如果我将代码交给你重写,我就把它移到这样的地方:
private static EditSettings winEditSettings = null;
public static void WakeUp()
{
if (winEditSettings == null)
{
winEditSettings = new EditSettings();
}
winEditSettings.Activate(); // This may need to be inside the block above
winEditSettings.Show();
}
这两个都是类(static
)的一部分,而不是实例。因此,您的应用程序对象在原始EditSettings.WakeUp()
内调用MenuItem_Click()
,并且实际上从未实际看到子窗口。
如果您稍后改变对分离式架构的看法,顺便说一下,您可以为get
添加winEditSettings
访问者并让每个人都相当高兴。
答案 1 :(得分:1)
if (_adCst == null)
{
_adCst = new AddCustomerPage();
_adCst.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
_adCst.WindowState = System.Windows.WindowState.Normal;
_adCst.ResizeMode = System.Windows.ResizeMode.NoResize;
_adCst.Activate(); // This may need to be inside the block above
_adCst.Show();
}
else
{
if (!_adCst.IsLoaded == true)
{
_adCst = new AddCustomerPage();
_adCst.WindowStartupLocation = System.Windows.WindowStartupLocation.CenterScreen;
_adCst.WindowState = System.Windows.WindowState.Normal;
_adCst.ResizeMode = System.Windows.ResizeMode.NoResize;
_adCst.Show();
}
_adCst.Activate();
}
答案 2 :(得分:0)
对于有这个问题的其他人,我找到了另一个解决方案 - 除了它没有设法将打开的窗口置于前面(激活)之外。但是,它确实会阻止多次打开同一个窗口。
foreach (Window n in Application.Current.Windows)
if (n.Name == "winEditSettings")
{ winEditSettings.Activate(); }
else
{ winEditSettings.Show(); }
有人可以通过Activate()来推测窗口没有被带到前面的原因吗?
修改的
对于有这个问题的其他人,将winEditSettings.Activate()放在foreach循环之外会做我想要实现的所有事情:
foreach (Window n in Application.Current.Windows)
if (n.Name == "winEditSettings")
{ }
else
{ winEditSettings.Show(); }
winEditSettings.Activate();
这将阻止同一窗口的多个实例打开,如果用户尝试重新打开窗口,则会将窗口置于前面。
答案 3 :(得分:0)
我的建议是你设置某种形式的柜台。这将阻止打开多个窗口实例。
int windowOpen = 1;
private void button_Click(object sender, RoutedEventArgs e)
{
if (windowOpen == 1)
{
WindowA winA = new WindowA();
winA.Show();
windowOpen++; //increments windowOpen by 1, windowOpen will now = 2
}
else if (windowOpen > 1)
{
MessageBox.Show("Window is already open");
}
}
我希望这会有所帮助。