我们如何为窗口创建一个单例实例?

4

我搜索了如何在WPF中创建一个窗口的单例对象。

public static Test DefInstance
{
    get
    {
        if (formDefInstance == null)  // formDefInstance.IsDisposed
        {
            initializingDefInstance = true;
            formDefInstance = new cas18();
            initializingDefInstance = false;
        }
        return formDefInstance;
    }
    set { formDefInstance = value; }
}

但是forDefInstance.IsDisposed没有起作用,并抛出了一个错误。
有什么想法吗?

3
没有理由对这个问题进行负分评价。从代码示例中可以很清楚地看出他想要做什么:他只想打开窗口一次,但也想检测窗口是否关闭。然后就可以再次打开它,但屏幕上永远不应该有两个这样的窗口。我认为这是一个非常有趣的问题! - Thorsten Dittmar
3
@ThorstenDittmar说:“我不是那个给你点踩的人,但如果你写‘……出了问题并显示错误’却没有提供错误信息,就好比是在求点踩。” - Heinzi
1
@Heinzi 虽然这是真的,问题不完整,但我认为它不应该被踩。@ OP 请添加错误信息。 - ken2k
@ThorstenDittmar 同意,这听起来像是OP试图将winforms转换为WPF,并且“抛出错误”是在编译时发生的。 - ken2k
1
@ThorstenDittmar/ken2k:我认为这是正确的 - 我会说,在没有来自OP的编辑或澄清的情况下,这是一个合理的降低问题评分的原因。 (我自己没有投票,但我可以理解人们为什么会这样做。) - Dan Puzey
显示剩余4条评论
3个回答

0

我不知道这是否是你想要做的,但对我来说它有效:

private static MyWindow _defInstance;
public static MyWindow DefInstance
{
    get
    {
        if (null == _defInstance)
        {
            _defInstance = new MyWindow();
        }
        return _defInstance;
    }
 }

在我的窗口代码中:
protected override void OnClosing(System.ComponentModel.CancelEventArgs e)
{
    this.Visibility = Visibility.Hidden;
    e.Cancel = true;
}

使用它的方法是:
DefInstance.Show();

然后,只显示一个窗口,并使用一个窗口实例。


0

我认为每个人都应该看一下Jon Skeet的C# In Depth网站。即使只是阅读并将单例模式(a-la C#)永久地烙印在他们的大脑中。

http://csharpindepth.com/Articles/General/Singleton.aspx

在您的情况下,请尝试实现以下内容(线程安全,非懒加载):
public sealed class DefInstance
{
  private static readonly DefInstance instance = new DefInstance();
  static DefInstance()
  {
  }

  private DefInstance()
  {
  }

  public static DefInstance Instance
  {
    get
    {
      return instance;
    }
   }
} 

该网站还提供了Lazy<T>实现以及其他各种模式的实现。


-2

你可以通过实现以下方法来实现这个目标

private static volatile DefInstance instance;
private static object syncRoot = new Object();

private DefInstance() {}

public static DefInstance Instance
{
   get 
   {
      if (instance == null) 
      {
         lock (syncRoot) 
         {
            if (instance == null) 
               instance = new DefInstance();
         }
      }

      return instance;
   }
}

哇!为什么要使用volatile?单例的目标是创建一次并防止后续实例创建。volatile关键字使得可以创建一个或多个后续实例并将其分配给DefInstance。请改用readonly - code4life
变量被声明为volatile,以确保在访问实例变量之前完成对实例变量的赋值。 - Shafqat Masood
1
private static readonly DefInstance instance = new DefInstance() 确保线程安全和可访问性,并防止后续的写入。而 volatile 则不具备这些特性。 - code4life
请阅读此问题的答案,您将能够知道为什么我提到要使用volatile.. https://dev59.com/fHI-5IYBdhLWcg3wN1hD - Shafqat Masood
我在示例中提到了双重检查锁定方法。如果想要了解更多相关概念,可以参考这篇文档:http://en.wikipedia.org/wiki/Double-checked_locking。 - Shafqat Masood
维基百科的例子正好引用了我所说的:“private static readonly”。顺便说一句,那个-1不是我给的...我只是在评论而已。 - code4life

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接