WPF ItemsSource работает в коде позади, но не в XAML - PullRequest
2 голосов
/ 09 июня 2011

У меня есть простой комбинированный список с установленным внутри флажком:

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

Текст данных - это просто код, и для его проверки я использую следующий код:

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 = "".Кто-нибудь знает почему?

Спасибо

Ответы [ 4 ]

3 голосов
/ 09 июня 2011

Вам необходимо присвоить DataContext элементу управления. что-то вроде:

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

где Window1 класс содержит комбобокс, а WindowDC имеет вид:

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

Вот как это будет работать.

То, что вы на самом деле делаете, это то, что вы помещаете collection в контрольный класс и устанавливаете ваш текст данных только для выпадающего списка.

Но для целей тестирования вы все равно можете установить Combox.Datacontext в конструкторе управления.

2 голосов
/ 09 июня 2011

Привязки в WPF всегда имеют источник. Если вы не укажете источник в самой привязке, он будет неявно использовать DataContext элемента управления или его предка. Поэтому, если вы хотите привязать свойства к вашему файлу codebehind, вы должны установить DataContext для объекта класса, который содержит свойство collection. В вашем случае это экземпляр Window (this).

DataContext = this;

Как отметил комментатор, не рекомендуется использовать бизнес-логику или данные внутри кода за файлом. Поэтому подумайте о написании отдельного класса, который содержит ваше свойство collection и который вы можете использовать для инициализации вашего DataContext. Если вы пишете большие приложения, вам следует взглянуть на шаблоны, такие как MVVM, которые используют привязку данных для лучшего разделения между вашим представлением и вашей моделью.

Редактировать: изменен порядок и встроенная обратная связь

0 голосов
/ 09 июня 2011

Это работает, когда вы устанавливаете источник элемента комбо в коде позади, потому что источник комбо обновляется, как мудро, чтобы установить источник элемента в 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. Надеюсь, это поможет вам

0 голосов
/ 09 июня 2011

Убедитесь, что в вашем коде есть открытое свойство 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");
    }
...