2013-04-30 90 views
0

我有一个带有ObservableCollection属性的UserControl。该属性应该用于绑定,但我不希望它在程序集外部可见,以满足OOP的基本规则。这里是一个展示例子的作品,但是当我改变访问修饰符数据内部它不工作了:WPF ItemsSource内部集合

XAML:

<Window x:Class="WpfApplication3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" x:Name="Root"> 
    <ListBox ItemsSource="{Binding Data, ElementName=Root}"/> 
</Window> 

而后面的代码:

using System; 
using System.Windows; 
using System.Collections.ObjectModel; 

namespace WpfApplication3 
{ 
    public partial class MainWindow : Window 
    { 
     private readonly ObservableCollection<string> _data = new ObservableCollection<string>(); 
     public ObservableCollection<string> Data 
     { 
      get { return _data; } 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 
      Data.Add("XXX"); 
      Data.Add("YYY"); 
      new System.Threading.Thread(() => 
      { 
       for (int i = 0; i < 3; i++) 
       { 
        Dispatcher.Invoke(new Action(() => Data.Add("ZZZ " + i))); 
        System.Threading.Thread.Sleep(1000); 
       } 
      }).Start(); 
     } 
    } 
} 

实现此目标的最佳方法是什么?

谢谢你的努力。

+1

更好的模式是使用MVVM并在ViewModel上将对象保留为公共状态。我没有看到如何揭露公众获得破解封装你的例子。也许你应该问问自己“为什么”你想使财产内部。根据我的经验,使用访问修饰符无约束地锁定对象通常会导致头痛,并且在将来很难保留代码。 (例如,当想写单元测试) – Jras 2013-04-30 02:47:54

+0

我同意。然而,在我的具体情况下,我的UserControl的设计和行为很依赖于这些公共属性(它们也用于绑定),所以它可能会导致一个奇怪的行为,甚至是一个Exception,如果它们被程序员用我的UserControl库。 – 2013-04-30 02:57:08

+1

如果是这种情况,也许你不应该使用绑定并从代码隐藏修改集合。向ListBox添加一个名称将允许您在不暴露列表的情况下操作代码隐藏的数据。 – Jras 2013-04-30 03:01:50

回答

2

尝试设置的ItemSource在主窗口的构造函数私有的,内部的,或者虚拟财产

XAML:

<Window x:Class="WpfApplication3.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="350" Width="525" x:Name="Root"> 
    <ListBox Name="listbox"/> 
</Window> 

和代码背后

using System; 
using System.Windows; 
using System.Collections.ObjectModel; 

namespace WpfApplication3 
{ 
    public partial class MainWindow : Window 
    { 
     private readonly ObservableCollection<string> _data = new ObservableCollection<string>(); 
     internal ObservableCollection<string> Data 
     { 
      get { return _data; } 
     } 

     public MainWindow() 
     { 
      InitializeComponent(); 

      listbox.ItemSource = this.Data; 
      Data.Add("XXX"); 
      Data.Add("YYY"); 
      new System.Threading.Thread(() => 
      { 
       for (int i = 0; i < 3; i++) 
       { 
        Dispatcher.Invoke(new Action(() => Data.Add("ZZZ " + i))); 
        System.Threading.Thread.Sleep(1000); 
       } 
      }).Start(); 
     } 
    } 
} 
+0

噢,它确实有效:]那么对于其他(非收集)属性,我仍然会遇到这个问题,但是这肯定会回答我的问题,谢谢。 – 2013-04-30 03:00:15

0

WPF中的DataBinding仅适用于公共属性。

MSDN

属性您使用的绑定,绑定源属性必须 是你的类的公共属性。明确定义的接口 属性不能用于绑定的目的来访问,也不能保护, 有没有基础 实施