2011-06-09 38 views
2

我有一个复选框,一个简单的组合框里面是这样:WPF的ItemsSource工作在代码隐藏而不是在XAML

<ComboBox Height="23" HorizontalAlignment="Left" Margin="158,180,0,0" Name="comboBox1" VerticalAlignment="Top" Width="120" ItemsSource="{Binding collection}"> 
     <ComboBox.ItemTemplate> 
      <DataTemplate> 
       <StackPanel Orientation="Horizontal"> 
        <CheckBox Content="{Binding Name}"></CheckBox> 
       </StackPanel> 
      </DataTemplate> 
     </ComboBox.ItemTemplate> 
    </ComboBox> 

DataContext的仅仅是后面的代码,并对其进行测试我使用下面的代码:

public ObservableCollection<Foo> collection { get; set; } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     collection = new ObservableCollection<Foo>(); 
     this.comboBox1.ItemsSource = collection; 
     Foo f = new Foo("DSD"); 
     collection.Add(f); 
    } 

当我设置的ItemsSource为我的代码,然后它工作正常,但我想设置的ItemsSource在XAML,但它不使用XAML中上述工作。我也尝试将其设置为Path =“”。任何人都知道为什么?

谢谢

回答

3

您需要将DataContext分配给控件。是这样的:

var window = new Window1(); 
window.DataContext = new WindowDC(); 
window.Show(); 

其中Window1类包含组合框,并WindowDC是这样的:

public class WindowDC 
{ 
    public ObservableCollection<Foo> collection { get; set; } 
} 

这就是这将如何工作。

实际上,您将collection放入控件类中,并仅为combobox设置datacontext。

但是,出于测试目的,您仍然可以在控制构造器中设置Combox.Datacontext。

2

WPF中的绑定总是有一个源。如果你没有在绑定本身中指定源,那么它将隐式地使用控件的DataContext或它的祖先。因此,如果要绑定到代码隐藏文件中的属性,则必须将DataContext设置为包含collection属性的类的对象。在你的情况下,这是窗口的实例(this)。

DataContext = this;

正如评论人员指出的那样,它不被认为是将商业逻辑或数据置于文件后面的代码中的好样式。因此,请考虑编写一个单独的类,其中包含您的collection属性,您可以使用它来初始化DataContext。如果你正在写更大的应用程序,你应该看看像MVVM这样的模式,它使用数据绑定来提供视图和模型之间更好的分离。

编辑:更改排序并纳入反馈

+0

不要这样做。这只是错误的,它打破了DataContext的整个概念,它用于将buisnesslogic与perpersentation分开。不,不。 – 2011-06-09 11:56:22

+1

我觉得给我一个这样的倒退是不公平的。这个问题没有任何相关的背景。他只想知道为什么他的样本不起作用,我给了他缺失的链接。我们不在这里讨论架构的概念证明。这是一个例子,它不必解释如何使用MVVM等。请考虑收回这个downvote。 – aKzenT 2011-06-09 12:42:24

+0

在任何情况下,我都将您的反馈并入原始答案并添加了评论。 – aKzenT 2011-06-09 12:54:09

0

确保您的代码背后存在公共财产collection

后面的代码中也做 this.DataContext = this

最后落实INotifyPropertyChanged告诉认为你已经改变了收集,一旦你把它添加项目

public ObservableCollection<Foo> Collection 
{ 
get 
    { 
    return collection; 
    } 
set 
    { 
    collection = value; 
    OnPropertyChanged("Collection"); 

    } 

    private void button1_Click(object sender, RoutedEventArgs e) 
    { 
     collection = new ObservableCollection<Foo>(); 
     //this.comboBox1.ItemsSource = collection; 
     Foo f = new Foo("DSD"); 
     collection.Add(f); 
     OnPropertyChanged("Collection"); 
    } 
+0

INotifyPropertyChanged不是必需的。 DataContext在button_click()中未被更改 – 2011-06-09 12:02:21

0

当你设置组合的项目据工作源代码在后面,因为组合的来源正在像明智更新设置XAML中的项目源,你必须使用INotifyPropertyChanged做一个属性,每当你通过这个属性更新你的集合时不断更新组合的itemsource。

private ObservableCollection<Foo> _Collection; 
public ObservableCollection<Foo> Collection 
{ 
get 
{ 
return collection; 
} 
set 
{ 
collection = value; 
OnPropertyChanged("Collection"); 
} 

现在,当您要填写按钮集合点击你只需要设置集合中的财产..

_Collection = new ObservableCollection<Foo>(); 
Foo f = new Foo("DSD"); 
_Collection .Add(f); 
    Collection = _Collection ; //here property call OnPropertyChange 

喜欢聪明人,你可以提供数据给任何控制。它是INotifyPropertyChanged属性的游戏。 希望这会帮助你

相关问题