WPF ItemsSource works in code-behind but not in XAML

对着背影说爱祢 提交于 2020-01-04 14:03:04

问题


I have a simple combobox with a checkbox inside as such:

<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>

The datacontext is simply the code behind, and to test it I use the following code:

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);
    }

When I set the ItemsSource as I have in the code, then it works fine, but I want to set the ItemsSource in the Xaml, however it does not work using the Xaml above. I have also tried setting it to Path = "". Anybody know why?

Thanks


回答1:


You need to assign DataContext to the control. something like:

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

where Window1 class contains the combobox, and WindowDC is like:

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

That's how this will work.

What you actually do is that you place collection into control class, and set your datacontext for combobox only.

But, for testing purposes, you can still set Combox.Datacontext in control constuctor.




回答2:


Bindings in WPF always have a Source. If you don't specify the source in the binding itself, then it will implicitly use the DataContext of the control or an ancestor of it. So if you want to bind to properties in your codebehind file, you have to set the DataContext to an object of the class which contains the collection property. In your case this is the instance of the Window (this).

DataContext = this;

As the commentor pointed out, it's not considered good style putting business logic or data inside the code behind file. So consider writing a separate class which contains your collection property and which you can use to initalize your DataContext. If you are writting bigger applications you should take a look at patterns like MVVM, which uses databinding to provide a better separation between your view and your model.

Edit: Changed ordering and incorporated feedback




回答3:


Make sure there exist a public property collection in your code behind.

in the code behind also do this.DataContext = this

Finally implement INotifyPropertyChanged to tell the view that you have changed the collection once you add items in it

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");
    }



回答4:


It is working when you are setting combo's item source in code behind because the source of combo is getting updated like wise to set the item source in XAML you have to make a property with INotifyPropertyChanged that keep update the combo's itemsource every time you update your collection via this property..

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

Now as you are filling collection on button click you just have to set that collection in the property as..

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

like wise you can provide data to any control. It is jsut the game of INotifyPropertyChanged property. Hope this will help you



来源:https://stackoverflow.com/questions/6292271/wpf-itemssource-works-in-code-behind-but-not-in-xaml

标签
易学教程内所有资源均来自网络或用户发布的内容,如有违反法律规定的内容欢迎反馈
该文章没有解决你所遇到的问题?点击提问,说说你的问题,让更多的人一起探讨吧!