2013-05-30 3 views
4

У меня есть ComboBox, связанный с коллекцией животных. Из него я выбираю своего любимого животного. Мне нужен статический нулевой элемент над связанными элементами. Я объявляю это с помощью CompositeCollection. Когда ComboBox связан с ним, не выбирает моего первоначального любимого животного. Как я могу это исправить? Аналогичная проблема here, но все еще не решена.ComboBox не выбирает правильный элемент при привязке к CompositeCollection

Наблюдения:

  • Переплет статическому элемента работы, т.е. если у меня нет начального любимое животное получает выбранный статический элемент.
  • Проблема исчезает, если статический элемент удален. Конечно, это сделало бы CompositeCollection и весь этот вопрос устаревшим.

Я уже применял эти меры:

  • CollectionContainer не могут связываться непосредственно к собственности, как указано here.
  • Композитная коллекция также перемещается на статический ресурс, как предложено here.

Complete C# код и XAML, чтобы продемонстрировать проблему:

using System; 
using System.Collections.Generic; 
using System.Windows; 
using System.Windows.Controls; 

namespace WpfApplication1 
{ 
    public class Animal 
    { 
     public int Id { get; set; } 
     public string Name { get; set; } 
    } 

    public class Zoo 
    { 
     private IEnumerable<Animal> _animals = new Animal[] 
     { 
      new Animal() { Id = 1, Name = "Tom" }, 
      new Animal() { Id = 2, Name = "Jerry" } 
     }; 

     public Zoo(int initialId) 
     { 
      FavouriteId = initialId; 
     } 

     public int FavouriteId { get; set; } 
     public IEnumerable<Animal> Animals { get { return _animals; } } 
    } 

    public partial class MainWindow : Window 
    { 
     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     private void BindComboBox(object sender, RoutedEventArgs e) 
     { 
      // Selecting the static item by default works. 
      //DataContext = new Zoo(-1); 

      // Selecting "Jerry" by default does not work. 
      DataContext = new Zoo(2); 
     } 
    } 
} 

XAML

<Window x:Class="WpfApplication1.MainWindow" 
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
    xmlns:local="clr-namespace:WpfApplication1"> 

    <Window.Resources> 
     <CollectionViewSource x:Key="AnimalsBridge" Source="{Binding Path=Animals}" /> 

     <CompositeCollection x:Key="AnimalsWithNullItem"> 
      <local:Animal Id="-1" Name="Pick someone..."/> 
      <CollectionContainer Collection="{Binding Source={StaticResource AnimalsBridge}}" /> 
     </CompositeCollection> 
    </Window.Resources> 

    <StackPanel> 
     <Button Content="Bind" Click="BindComboBox"/> 

     <ComboBox x:Name="cmbFavourite" 
      SelectedValue="{Binding Path=FavouriteId}" 
      SelectedValuePath="Id" DisplayMemberPath="Name" 
      ItemsSource="{StaticResource AnimalsWithNullItem}"/> 
    </StackPanel> 
</Window> 

ответ

4

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

Для примера добавить:

public class ZooViewModel 
{ 
    ..... 


    public IEnumerable<Animal> Animals { get { return _animals; } } 
    public IEnumerable<Animal> AnimalsWithNull { get { return _animals.WithDefault(new Animal() { Id = -1, Name = "Please select one" }); } } 
} 

Волшебный компонент

public static class EnumerableExtend { 

    public static IEnumerable<T> WithDefault<T>(this IEnumerable<T> enumerable,T defaultValue) { 
     yield return defaultValue; 
     foreach (var value in enumerable) { 
      yield return value;  
     } 
    } 
} 

Затем в XAML вы просто связываются с

ComboBox x:Name="cmbFavourite" 
     SelectedValue="{Binding Path=FavouriteId}" 
     SelectedValuePath="Id" DisplayMemberPath="Name" 
     ItemsSource="{Binding AnimalsWithNull }"/> 

Теперь вы привязки непосредственно к источнику и может контролировать привязку как обычно. Также обратите внимание, потому что мы используем «yield», мы не создаем новое перечисление, а просто повторяем существующий список.

+0

+1 для черной магии урожая. Мне все же пришлось использовать конвертер, чтобы правильно установить свойство ListViewItem из выбранного значения ComboBox. – helloserve

+0

Маркировка как ответ, потому что решение, похоже, не существует. Элементы могут быть добавлены эффективно с помощью встроенных методов: 'new [] {new Animal() {...}} .Concat (_animals)' – idilov

 Смежные вопросы

  • Нет связанных вопросов^_^