2013-04-08 3 views
0

Мой маленький проект выглядит совсем по-другому. Теперь у меня есть ObservableCollection PackagesList с данными, которые я хочу связать с целым DataGrid (через Binding Path) и ObservableCollection DestinationItememsSource, где хранятся случаи для DataGridComboboxColumn (как ItemsSourceBinding). Свойство SelectedItem в DatagridComboboxColumn - одно значение от PackageInfo (и оно является одним из DestinationNames случаев ofc). Привязка к DatagridTextBoxColumns в порядке.ObservableCollection с INotifyPropertyChanged в DatagridComboboxColumn Binding

XAML:

<Window x:Class="test01.MainWindow" 
     xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 
     xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
     Title="MainWindow" Height="300" Width="400" Loaded="Window_Loaded"> 
    <Grid> 
     <Border x:Name="mainBorder" Margin="20"> 
      <DataGrid x:Name="mainDataGrid" x:Uid="mainDataGrid" AutoGenerateColumns="False" 
         AlternationCount="2" SelectionMode="Single" HorizontalAlignment="Stretch"> 
       <DataGrid.Columns> 
        <DataGridTextColumn Binding="{Binding Path=id}" 
            Header="ID" Width="Auto" IsReadOnly="True"/> 
        <DataGridTextColumn Binding="{Binding Path=name}" 
            Header="Name" Width="Auto" IsReadOnly="True"/> 
        <DataGridTextColumn Binding="{Binding Path=quantity}" 
            Header="Quantity" Width="Auto" IsReadOnly="True"/> 
        <DataGridTextColumn Binding="{Binding Path=price}" 
            Header="Price" Width="Auto" IsReadOnly="True"/> 
        <DataGridComboBoxColumn ItemsSource="{Binding DestinationItemsSource}" 
                SelectedItemBinding="{Binding Path=destination, UpdateSourceTrigger=PropertyChanged}" 
                Header="Destination" Width="Auto"/> 
       </DataGrid.Columns> 
      </DataGrid> 
     </Border> 
    </Grid> 
</Window> 

C#:

public class PackageInfo 
    { 
     public int id { get; set; } 
     public string name { get; set; } 
     public int quantity { get; set; } 
     public double price { get; set; } 
     public string destination { get; set; } 
    } 

    public class DestinationNames : INotifyPropertyChanged 
    { 
     public string name { get; set; } 

     public event PropertyChangedEventHandler PropertyChanged; 

     public DestinationNames(string value) 
     { 
      this.name = value; 
     } 

     public string DestinationName 
     { 
      get { return name; } 
      set 
      { 
       name = value; 
       OnPropertyChanged("DestinationName"); 
      } 
     } 

     protected void OnPropertyChanged(string name) 
     { 
      PropertyChangedEventHandler handler = PropertyChanged; 
      if (handler != null) 
      { 
       handler(this, new PropertyChangedEventArgs(name)); 
      } 
     } 
    } 


    public partial class MainWindow : Window 
    { 
     public ObservableCollection<DestinationNames> DestinationItememsSource { get; set; } 
     public ObservableCollection<PackageInfo> PackagesList { get; set; } 

     public MainWindow() 
     { 
      InitializeComponent(); 
     } 

     public void Window_Loaded(object sender, RoutedEventArgs e) 
     { 
      LoadPackages(); 
     } 

     public void LoadPackages() 
     { 
      DestinationItememsSource = new ObservableCollection<DestinationNames>(); 
      DestinationItememsSource.Add(new DestinationNames("London")); 
      DestinationItememsSource.Add(new DestinationNames("Plymouth")); 
      DestinationItememsSource.Add(new DestinationNames("Birmingham")); 
      DestinationItememsSource.Add(new DestinationNames("Cambridge")); 

      PackagesList = new ObservableCollection<PackageInfo>(); 
      PackagesList.Add(new PackageInfo { id = 1, name = "Potato", quantity = 3, price = 2.2, destination = "London" }); 
      PackagesList.Add(new PackageInfo { id = 2, name = "Tomato", quantity = 5, price = 3.8, destination = "Plymouth" }); 
      PackagesList.Add(new PackageInfo { id = 3, name = "Carrot", quantity = 1, price = 5.1, destination = "London" }); 
      PackagesList.Add(new PackageInfo { id = 4, name = "Pea", quantity = 6, price = 1.8, destination = "Plymouth" }); 
      PackagesList.Add(new PackageInfo { id = 5, name = "Bean", quantity = 2, price = 1.5, destination = "Birmingham" }); 
      mainDataGrid.ItemsSource = PackagesList; 
     } 
    } 

Как связать этот DatagridComboboxColumn правильно? Должен ли я использовать INotifyCollectionChanged ?? Что делать, если я хочу, чтобы все данные в datagrid были автоматически синхронизированы с ObservableCollection ?? Пожалуйста, помогите с некоторым примером.

ответ

0

Ваша привязка к DestinationItememsSource не работает, потому что она не является частью объекта PackageInfo. Вы также не можете привязываться к Windows DataContext через привязку FindAncestor или ElementName, потому что DataGrid-Columns не будут добавлены в визуальное дерево.

Одно решение, которое я могу вспомнить, используя CollectionViewSource:

<Window.Resources> 
    <CollectionViewSource Source="{Binding RelativeSource={RelativeSource Self}, Path=DestinationItememsSource}" x:Key="destinations"> 
     <!--here you can also add Group and SortDescriptions--> 
    </CollectionViewSource> 
</Window.Resources> 
<DataGridComboBoxColumn ItemsSource="{Binding Source={StaticResource ResourceKey=destinations}}".../> 

Я не могу проверить его атм, потому что я все еще скачивании VS 2012 ^^

AnotherOne будет просто добавить. Список назначений на объект PackageInfo (но это приведет к большому количеству избыточности).

0

Имейте PackageInfo реализуйте INotifyPropertyChanged.

Наблюдаемая коллекция автоматически реализует INotifyCollectionChanged.

Вам нужно будет добавить лист или ObservableCollection назначения как свойство PackageInfo
ОТСУТСТВИЕ DestinationNames класса
Просто класс DestinationName