【问题标题】:App-wide Observable Collection应用范围的可观察集合
【发布时间】:2013-02-18 13:33:22
【问题描述】:

如果我将 Observable 集合放在一个单独的 .cs(类)文件中并在我的 MainPage.xaml 中使用它,我怎样才能使所有数据都存储在同一个文件中以后可以从不同的 XAML 页面中访问 Observable Collection 吗?

例如

MyClass.cs:
public ObservableCollection<String> oC = new ObservableCollection<String>();

MainPage.xaml.cs:
// add to observable collection

SecondPage.xaml.cs:
// access and use data stored in ObservableCollection

【问题讨论】:

    标签: c# .net xaml windows-8 microsoft-metro


    【解决方案1】:

    您可以将集合声明为静态成员。

    或者实现单例模式。

    当您在 XAML 中绑定到集合时,您需要在视图模型中创建一个访问器。

    public ObservableCollection<String> Accessor
    {
      get
      {
        return MyClass.oC;
      }
    }
    

    【讨论】:

      【解决方案2】:

      一种简单的方法是将其声明为静态并通过类型而不是实例来访问它:

      例如

      class SomeClass 
      {
          public static bool SomeBool = false;
      }
      
      class SomeOtherClass
      {
          public void SomeMethod() 
          {
              Debug.Write(SomeClass.SomeBool); // Ouput = false
          }
      }
      

      请记住,这个 observable 将是静态的,因此是一个实例 - 对它的任何修改都将立即对所有访问它的对象可见 - 这意味着如果一些代码正在迭代 observable 并且另一个代码尝试从中添加/删除- 迭代器会抛出异常

      如果是这种情况,请考虑替代方案或使用锁定来确保对集合的单线程访问

      【讨论】:

      • 谢谢@Charleh :) 问这个问题有点尴尬。有时我的记忆似乎只是在休假。
      • 不用尴尬,这是一个很好的问题。对于简单的项目,我自己喜欢静态类。我将它们大致称为“服务”,例如 ProductService 或 PackageManager。他们完成了所有繁重的工作,并使我的 ViewModel 更苗条。如果您的项目变得更加复杂并且您发现服务开始依赖其他服务,您可能会考虑升级到真正的 IoC 容器和依赖注入。但是对于大多数简单的项目,静态类是一个很好的最小有效剂量。
      【解决方案3】:

      好吧,这样的事情怎么样。无处不在的资源...

      public class CollectionSrc
      {
        public ObservableCollection<...> Col 
        { 
          get { return _col ?? (_col = new ObservableCollection<...>()); }
        }
      }
      

      App.xaml

      &lt;ns:CollectionSrc x:Key="ColSrc" /&gt; &lt;!--ns .. the namespace of CollectionSrc--&gt;

      现在您可以在 xaml 代码中的任何位置访问ColSrc。例如

      &lt;ListBox ItemsSource={Binding Col, Source={StaticResource ColSrc}} /&gt;

      【讨论】:

      • 这种模式适用于对其他服务没有任何依赖关系的简单对象,并且您不需要控制它的创建时间(它总是在应用程序加载时创建Xaml 解析器解析 App.xaml 资源部分)。如果您需要更多地控制创建对象的时间,或者如果您需要提供依赖项,那么下面提到的单例和静态选项是您更好的选择。由于问题是关于一个简单的 ObservableCollection,因此这种方法效果很好。
      • 我会说这是大多数情况下的最佳选择。您可以将CollectionSrc 重命名为ViewModelLocator,它会突然看起来更熟悉。然后你也可以称它为ServiceLocator 并且你对模式有了更多的了解。然后,您可以修改您的属性以使用某种 IoC(控制反转)容器,以便检索该集合的方法更具可定制性,并且您处于设计模式的必杀技。 :)
      • @JaredBienz-MSFT 嗯,我真的不明白你的意思。我还可以想象一个更复杂的对象,它表现出更复杂的行为。你能举一个例子,我的建议不起作用吗?另一个优点是,我的解决方案也适用于旧版本的 SL,尽管在这些日子里它并不那么重要。 ;o)
      • @FilipSkakun 有趣的一点。从来没有想过,将它用作访问 ViewModel 或服务的入口点。感谢这个提示。 :o)
      【解决方案4】:

      我想你只是想要这个:

      MyClass.cs:
      public static ObservableCollection<String> oC = new ObservableCollection<String>();
      
      MainPage.xaml.cs:
      // add to observable collection
      
      SecondPage.xaml.cs:
      // access and use data stored in ObservableCollection
      

      一旦oC 是静态的,您就可以从任何类/页面一次又一次地引用它。

      但是,如果您想绑定到它(因为您无法绑定到 Windows 8 应用程序中的字段或静态属性),您需要让该 XAML 页面在一个简单属性中引用您的静态属性:

      SecondPage.xaml.cs:
      public static ObservableCollection<String> oC { get { return MyClass.oC; } }
      

      我希望这是有道理的!

      【讨论】:

        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 1970-01-01
        • 2013-05-21
        • 1970-01-01
        • 1970-01-01
        相关资源
        最近更新 更多