Bindowanie ObservableCollection z INotifyPropertyChanged do DatagridComboboxColumn

0

Witam.
Mam ObservableCollection PackagesList z której obiekty chciałbym zbindować do całego DataGridu oraz ObservableCollection DestinationItememsSource gdzie przechowuję przypadki dla DataGridComboboxColumn(ItemsSourceBinding). Pole SelectedItem w DatagridComboboxColumn jest odpowiednim obiektem z PackageInfo (oraz z DestinationNames oczywiście). Bindowanie do DatagridTextBoxColumns działa bez zarzutu.

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

Jak poprawnie zbindować DatagridComboboxColumn ?? Co zrobić by cała kolekcja była synchronizowana automatycznie we dwie strony z DataGride'm ??
Byłbym bardzo wdzięczny za przykładowy kod.

0

up!

0
<Window x:Class="WpfApplication1.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:core="clr-namespace:System;assembly=mscorlib"
        xmlns:local="clr-namespace:WpfApplication1"
        Title="MainWindow" Height="350" Width="525" Loaded="Window_Loaded">
    <Window.Resources>
        <ObjectDataProvider x:Key="destEnum" MethodName="GetValues" ObjectType="{x:Type core:Enum}">
            <ObjectDataProvider.MethodParameters>
                <x:Type Type="local:eDestination" />
            </ObjectDataProvider.MethodParameters>
        </ObjectDataProvider>
    </Window.Resources>
    <Grid>
        <Border x:Name="mainBorder" Margin="20">
            <DataGrid Name="mainDataGrid" AutoGenerateColumns="False" AlternationCount="2"
                      SelectionMode="Single" HorizontalAlignment="Stretch">
                <DataGrid.Columns>
                    <DataGridTextColumn Binding="{Binding ID}"  Header="ID" Width="50"
                                        IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Name}" Header="Name" Width="*"
                                        IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Quantity}" Header="Quantity"
                                         Width="80" IsReadOnly="True" />
                    <DataGridTextColumn Binding="{Binding Price}" Header="Price"  Width="80"
                                        IsReadOnly="True" />
                    <DataGridComboBoxColumn Header="Destination" Width="120"
                                            ItemsSource="{Binding Source={StaticResource destEnum}}"
                                            SelectedItemBinding="{Binding Destination}" />
                </DataGrid.Columns>
            </DataGrid>
        </Border>
    </Grid>
</Window>
using System.Collections.ObjectModel;
using System.Windows;

namespace WpfApplication1
{
    public enum eDestination { London, Plymouth, Birmingham, Cambridge };

    public struct PackageInfo
    {
        public int ID { get; set; }
        public string Name { get; set; }
        public int Quantity { get; set; }
        public double Price { get; set; }
        public eDestination Destination { get; set; }
    }

    public partial class MainWindow : Window
    {
        public ObservableCollection<PackageInfo> PackagesList = new ObservableCollection<PackageInfo>();

        public MainWindow()
        {
            InitializeComponent();

            mainDataGrid.DataContext = PackagesList;
            mainDataGrid.ItemsSource = PackagesList;
        }

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

        public void LoadPackages()
        {
            PackagesList.Add(new PackageInfo { ID = 1, Name = "Potato", Quantity = 3,
                Price = 2.2, Destination = eDestination.London });

            PackagesList.Add(new PackageInfo { ID = 2, Name = "Tomato", Quantity = 5,
                Price = 3.8, Destination = eDestination.Plymouth });

            PackagesList.Add(new PackageInfo { ID = 3, Name = "Carrot", Quantity = 1,
                Price = 5.1, Destination = eDestination.London });

            PackagesList.Add(new PackageInfo { ID = 4, Name = "Pea", Quantity = 6,
                Price = 1.8, Destination = eDestination.Plymouth });

            PackagesList.Add(new PackageInfo { ID = 5, Name = "Bean", Quantity = 2,
                Price = 1.5, Destination = eDestination.Birmingham });
        }
    }
}
0

Niestety, nie takie rozwiązanie miałem na myśli. Jak pisałem poszukuję rozwiązania wykorzystującego kolekcję, a jest to spowodowane tym, iż w zamierzeniu dane będą do takowej kolekcji pakowane z sql'a i w zależności od przypadku różnią się. Enum odpada.

0

Chodzi Ci o bindowanie dwustronne? Jeżeli dobrze zrozumiałem to wystarczy abyś ustawił {Binding=NazwaProperty,Mode=TwoWay} tutaj masz opis: http://msdn.microsoft.com/en-us/library/system.windows.data.binding.mode.aspx

0
maze napisał(a):

Chodzi Ci o bindowanie dwustronne? Jeżeli dobrze zrozumiałem to wystarczy abyś ustawił {Binding=NazwaProperty,Mode=TwoWay} tutaj masz opis: http://msdn.microsoft.com/en-us/library/system.windows.data.binding.mode.aspx

Całą istotę problemu dokładnie opisałem w pierwszym poście. Sugeruję po prostu skopiowanie kodu z dwóch moich listingów i przetestowanie aplikacji.
Pozdrawiam i życzę Wesołych Świąt :D

0

up!

0
irfActive napisał(a):

Całą istotę problemu dokładnie opisałem w pierwszym poście. Sugeruję po prostu skopiowanie kodu z dwóch moich listingów i przetestowanie aplikacji.
Pozdrawiam i życzę Wesołych Świąt :D

Założony temat 2013-03-02 00:31. Jak tak dalej będziesz się za zabierał to za niedługo będziesz życzył Szczęśliwego Nowego Roku.

Każda zmiana w ObservableCollection dodanie/usunięcia zostanie od razu odnotowana nic nie trzeba kombinować.

0
DibbyDum napisał(a):
irfActive napisał(a):

Całą istotę problemu dokładnie opisałem w pierwszym poście. Sugeruję po prostu skopiowanie kodu z dwóch moich listingów i przetestowanie aplikacji.
Pozdrawiam i życzę Wesołych Świąt :D

Założony temat 2013-03-02 00:31. Jak tak dalej będziesz się za zabierał to za niedługo będziesz życzył Szczęśliwego Nowego Roku.

Każda zmiana w ObservableCollection dodanie/usunięcia zostanie od razu odnotowana nic nie trzeba kombinować.

To jest oczywiste. Proszę o wypowiedzi wnoszące coś konstruktywnego do tematu lub najlepiej rozwiązujące problem, a nie bezsensownego nabijania sobie liczby postów(i minusowania moich wypowiedzi).
Ponadto, stworzenie nowego projektu w VS oraz skopiowanie kodu z pierwszego postu nie zajmuje nawet minuty, dlatego nie widzę problemu aby swoją wypowiedź poprzedzić sprawdzeniem czy proponowane rozwiązanie rzeczywiście rozwiązuje mój problem.

I bardzo proszę nie doszukujcie się w moich wypowiedziach nie wiadomo jakiego hejtu czy złośliwości bo ich tam nie ma. Proszę tylko o pomoc osób które znają rozwiązanie problemu. Tyle.

0

Twoje pytanie:

Co zrobić by cała kolekcja była synchronizowana automatycznie we dwie strony z DataGride'm ??

Odpowiedziałem ObservableCollection robi to automatycznie. Wiec nie rozumiem Twojego problemu. Jak nie oto Ci chodziło to po prostu wytłumacz o co a nie odsyłaj do swojego pierwszego postu.

Następna sprawa:
Tutaj nie używasz Bindinga:

mainDataGrid.ItemsSource = PackagesList;

to czemu go dałeś tutaj:

ItemsSource="{Binding DestinationItemsSource}"

jakaś nie konsekwencja.

Następna sprawa czemu do jednego DataGrida pakujesz dwie kolekcje nie mające nic ze sobą wspólnego? Na jakiej zasadzie mają ze sobą współgrać ?

1 użytkowników online, w tym zalogowanych: 0, gości: 1