【问题标题】:How to bind to singleton object instance如何绑定到单例对象实例
【发布时间】:2015-08-03 14:26:45
【问题描述】:

所以我有下一个类,称为 NavigationController,它将控制与导航相关的所有操作 - 菜单、页面、弹出窗口等:

public class NavigationController: INotifyPropertyChanged
{
    #region ~~~ Fields ~~~

    private NavigationController instance;

    private bool isNavigationMenuOpen;

    #endregion
    #region ~~~ Constructors ~~~

    private NavigationController()
    {

    }

    #endregion
    #region ~~~ Events ~~~

    public event PropertyChangedEventHandler PropertyChanged;

    #endregion
    #region ~~~ Properties ~~~

    public NavigationController Instance
    {
        get
        {
            if(instance==null)
            {
                instance = new NavigationController();
            }

            return instance;
        }
    }

    public bool IsNavigationMenuOpen
    {
        get
        {
            return isNavigationMenuOpen;
        }

        set
        {
            if (isNavigationMenuOpen != value)
            {
                isNavigationMenuOpen = value;
                PropertyChanged(this, new PropertyChangedEventArgs("IsNavigationMenuOpen"));
            }
        }
    }

    #endregion
    #region ~~~ Methods ~~~

    public void OpenNavigationMenu()
    {
        this.IsNavigationMenuOpen = true;
    }

    public void CloseNavigationMenu()
    {
        this.IsNavigationMenuOpen = false;
    }

    #endregion
}

在我的 MainPage.xaml 上,我有一个菜单,它有一个属性 IsPaneOpen,它以这种方式绑定:

IsPaneOpen="{Binding IsNavigationMenuOpen, Source={StaticResource NavigationController}}"

所以我将 NavigationController 添加为资源:

<Page.Resources>
    <controllers:NavigationController x:Key="NavigationController"/>
</Page.Resources>

并得到错误:

无法构造 XAML NavigationController 类型。为了 在 XAML 中构造的类型不能是抽象的、接口的、嵌套的、 泛型或结构,并且必须具有公共默认构造函数

但是上面的code3并没有绑定到一个实例,它会创建一个新的对象。 如何绑定到实例?

所以按照这里的建议,我改为:

private static NavigationController instance;


public static NavigationController Instance
    {
        get
        {
            if(instance==null)
            {
                instance = new NavigationController();
            }

            return instance;
        }
    }

还有路径:

<ToggleButton VerticalAlignment="Stretch" HorizontalAlignment="Stretch" IsChecked="{Binding Path=NavigationController.Instance.IsNavigationMenuOpen, Mode=TwoWay, Source={StaticResource NavigationController}}">
        <Image Source="ms-appx:///Assets/Icons/menu-icon.png"></Image>
    </ToggleButton>

并公开构造函数

当我在一个控件中切换按钮时,另一个控件没有反应。 有什么问题?我认为为每个控件创建了两个实例...

【问题讨论】:

  • "and must have a public default constructor" 似乎错误很明显...要绑定到实例,请将绑定路径设置为该实例,例如@987654326 @.
  • 添加了修改请看一下

标签: c# xaml windows-store-apps win-universal-app


【解决方案1】:

您需要在 XAML 中引用该 Instance 属性。因此,在绑定时,您需要在其中添加点(并从 Instance 中删除静态)。

Instance.IsNavigationMenuOpen

但是,如另一个答案所示,请考虑新设计。也许构建一个新类型,公开一个所有其他控制器类型都可以引用的单例实例。这样,至少,它解开了一点。

【讨论】:

  • 是的,你是对的,如果我使用 Path=Instance.IsNavigationMenuOpen 而不是 Path=NavigationController.Instance.IsNavigationMenuOpen 一切正常。谢谢
  • 另一方面,您可能应该重新访问该实例的 getter 并确保只有一个线程可以设置它。查看双重检查锁定(这对 C# 非常有用)或内置的 Lazy 类。或者,更简单地说,只需将其移至静态构造函数,因为我猜您总是希望创建它。
【解决方案2】:

要正确实现单例模式,Instance 属性应该是静态的

【讨论】:

  • 进一步阅读您的问题,您似乎无法在此处实现单例模式。要正确实现此模式,您需要将构造函数设为私有,但 WPF 似乎不允许这样做。你的班级必须是单身人士有什么原因吗?
  • 许多控件将使用它来相互通信。例如,标题中的 ToggleButton 将具有双向绑定,因此我单击切换按钮,左侧菜单开始显示动画。当我选择某个页面时 - 标题将更改标题等。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2011-11-20
  • 1970-01-01
  • 1970-01-01
  • 2013-05-27
  • 2021-12-16
  • 2011-01-17
相关资源
最近更新 更多