WPF ItemsSource在代码隐藏中工作,但在XAML中不起作用

时间:2011-06-09 11:46:35

标签: c# wpf itemssource

我有一个简单的组合框,里面有一个复选框:

<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时,它工作正常,但我想在Xaml中设置ItemsSource,但是它不能使用上面的Xaml。我也尝试将其设置为Path =“”。有谁知道为什么?

由于

4 个答案:

答案 0 :(得分:3)

您需要将DataContext分配给控件。类似的东西:

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

其中Window1类包含组合框,而WindowDC类似于:

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

这就是它的运作方式。

您实际执行的操作是将collection放入控件类,并仅为组合框设置datacontext。

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

答案 1 :(得分:2)

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

  

DataContext = this;

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

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

答案 2 :(得分: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");
    }

答案 3 :(得分:0)

当您在代码中设置组合的项目源时,它正在工作,因为组合的来源正在更新,就像在XAML中设置项目源一样,您必须使用INotifyPropertyChanged创建一个属性,每次您都保持更新组合的项目源通过此属性更新您的收藏..

 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属性的游戏。 希望这会对你有所帮助