Jak dodac liste plikow do danego wiersza w tabeli

0

**Jak w temacie . Jak zsynchronizować załaczniki z plikami tak żeby lista plików była przypisana do wybranego wiersza w tabeli , w zaleźności od wiersza do którego je załączymy . Mam kod który dodaje załączniki ale te same do każdego wiersza w tabeli ? **

<DataGrid Name="ListaZamowien" ItemsSource="{Binding}"   AutoGenerateColumns="False" >
                 <DataGrid.Columns>
                   <DataGridTextColumn Header="Id"   Binding="{Binding IdZamowienia}"/>
                   <DataGridTextColumn Header="Zamówiony towar" Binding="{Binding TowarZamowiony}" />
                   <DataGridTextColumn Header="Kontrahent" Binding="{Binding Kontrahent}" />
                   <DataGridTextColumn Header="Data zamówienia" Binding="{Binding DataZamowienia, StringFormat=d}" />
                   <DataGridTextColumn Header="Kwota zamówienia" Binding="{Binding KwotaZamowienia}" />
                   <DataGridTextColumn Header="Ilość" Binding="{Binding Ilosc}"/>
                   <DataGridTemplateColumn>
                       <DataGridTemplateColumn.CellTemplate>
                           <DataTemplate>
                               <StackPanel Orientation="Horizontal">
                                    <Button Content="Dodaj załącznik PDF" Width="170" Height="50" Click="GenerujZalacznikPDF"></Button>
                               </StackPanel>
                           </DataTemplate>
                       </DataGridTemplateColumn.CellTemplate>
                   </DataGridTemplateColumn>
                   <DataGridComboBoxColumn Width="100" x:Name="ListaPlikowDoZalaczenia" SelectedValueBinding="{Binding NazwaPliku, Mode=TwoWay}"    DisplayMemberPath="{Binding NazwaPliku}" >
                   </DataGridComboBoxColumn>
              </DataGrid.Columns>
          </DataGrid>

** i taki kod w modelu **

        private List<Zamowienia> listaZamowien2;
        public List<Zamowienia> ListaZamowien2 { get; set; }
        private List<PlikPDF> listaPlikow;
        public List<PlikPDF> ListaPlikow { get; set; }

        public ZamowieniaWindow()
        {
            InitializeComponent();
            this.listaZamowien2 = PobierzListeZamowien();
            ListaZamowien.DataContext = this.listaZamowien2;
            listaPlikow = new List<PlikPDF>();
        }


   private void GenerujZalacznikPDF(object sender, RoutedEventArgs e)
        {

            Zamowienia zamowienie = (Zamowienia)ListaZamowien.SelectedItems[0];

            System.Windows.MessageBox.Show(zamowienie.IdZamowienia.ToString());
            //   PlikPDF plikPDF = new PlikPDF();

            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.Filter = "Text files (*.pdf)|*.pdf|All files (*.*)|*.*";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            if (Convert.ToBoolean(openFileDialog.ShowDialog()) == true)
            {
                foreach (string filename in openFileDialog.FileNames)
                {
                    listaPlikow.Add(new PlikPDF(Path.GetFileName(filename)));
                    ListaPlikowDoZalaczenia.ItemsSource = (IEnumerable)listaPlikow;
                }
             }
0

Mieszasz nazwy zmiennych prywatnych i publicznych o podobnej nazwie. Twój DataGrid ma powiązanie kolekcji z DataContext. Twoj DataContext zawiera listę którą przypisałeś w konstruktorze w modelu. Nigdzie nie dodajesz ani nie usuwasz elementów tej listy

0

ok . Żle skopiowałem . Poniżej dodawanie elementów do listy. Powiedz mi coś więcej jak załączyć pliki do wiersza w datagridzie ?

 private static List<Zamowienie> PobierzListeZamowien()
        {
            List<Zamowienie> listaZamowien = MenadzerZamowienDB.PobierzListeZamowien();
            return listaZamowien;
        } 

** a tak pobieram z bazy**


 public static List<Zamowienie> PobierzListeZamowien()
        {
                MySqlConnection conn = null;
                MySqlDataReader rdr = null;
                Zamowienie zamowienia = null;
                List<Zamowienie> listaZamowien = new List<Zamowienie>();
             try
                {
                    conn = PolaczenieZBazaDanych();
                    string stm = "SELECT IdZamowienia ,kontrahent, towar_zamowiony, kwota_zamowienia, data_zamowienia,ilosc  FROM zamowienie ";
                
                    MySqlCommand cmd = new MySqlCommand(stm, conn);
                    rdr = cmd.ExecuteReader();
                    while (rdr.Read())
                    {
                        zamowienia = new Zamowienie();
                        zamowienia.IdZamowienia = rdr.GetInt32(0);
                        zamowienia.Kontrahent = rdr.GetString(1);
                        zamowienia.TowarZamowiony = rdr.GetString(2);
                        zamowienia.KwotaZamowienia = rdr.GetDouble(3);
                        zamowienia.DataZamowienia = Convert.ToString(rdr.GetDateTime(4));
                        zamowienia.Ilosc = rdr.GetInt32(5);
                        listaZamowien.Add(zamowienia);
                    }
                }
                catch (MySqlException ex)
                {
                }
                conn.Close();
                return listaZamowien;
        }
0

Najlepiej będzie tak:

  1. Zrób sobie klasę (elementy DataGrida, w której będziesz przechowywał dane o "wierszu"
public class PlikZamowienia : Zamowienie, INotifyPropertyChanged
        {
            public PlikZamowienia(Zamowienie zamowienie) : base(zamowienie)
            {
                PDF = null;
            }
            public PlikZamowienia(Zamowienie zamowienie, PlikPDF plikPDF) : base(zamowienie)
            {
                PDF = plikPDF;
            }

            private PlikPDF pDF = null;
            public PlikPDF PDF
            {
                get
                {
                    return pDF;
                }
                set
                {
                    pDF = value;
                    OnPropertyChanged("PDF");
                }
            }
        }

(Poczytaj o interfejsie INotifyPropertyChanged. Odpowiada on za informowanie widoku o zmianie właściwości)

  1. Teraz zmodyfikujemy obsługę zdarzenia:
/// <summary>
        /// Akcja po wciśnięciu przycisku wewnątrz elementu DataGrida
        /// </summary>
        /// <param name="sender">Obiekt który wysłał zdarzenie</param>
        /// <param name="e">Parametry pomocnicze</param>
        private void GenerujZalacznikPDF(object sender, RoutedEventArgs e)
        {

        }

Należy wspomnieć na wstępie, że DataContext posiada każda kontrolka i jeżeli nie określiliśmy go w kodzie będzie ona dziedziczyć DataContext po kontrolce - rodzicu.
Mając listę i bindując ją do DataContext w twoim DataGridzie

public IList<PlikZamowienia> ListaPlikow = new ObservableCollection<PlikZamowienia>();
MyDataGridName.DataContext = ListaPlikow;

każdy wiersz w datagridzie będzie miał osobny element o typie typeof(PlikZamowienia) który możemy pobrać z DataContext.

Przerabiając metodę wyjdzie coś takiego:

/// <summary>
        /// Akcja po wciśnięciu przycisku wewnątrz elementu DataGrida
        /// </summary>
        /// <param name="sender">Obiekt który wysłał zdarzenie</param>
        /// <param name="e">Parametry pomocnicze</param>
        private void GenerujZalacznikPDF(object sender, RoutedEventArgs e)
        {
            // przycisk jest elementem podrzędnym DataGrida. W dataContext znajduje się element z listy do którego przypisany jest wiersz 
            PlikZamowienia plik = (sender as Button).DataContext as PlikZamowienia;
            // pobierasz plik pdf za pomocą metody
            PlikPDF pdf = PobierzPDF(PlikZamowienia zamowienie);
            //Zmieniasz wartość w elemencie z listy
            plik.PDF = pdf;
        }
0

napisz coś więcej jak ma wyglądać ta metoda , bo gonię w piętkę i nie mogę dogonić ?

PlikPDF pdf = PobierzPDF(PlikZamowienia zamowienie);
0
jan kowal napisał(a):

napisz coś więcej jak ma wyglądać ta metoda , bo gonię w piętkę i nie mogę dogonić ?

PlikPDF pdf = PobierzPDF(PlikZamowienia zamowienie);

żeby twój kod miał szansę zadziałać , potrzebuję konstruktor bez parametrów z możliwością ustawienia zmiennych w klasie dziedziczącej . A takiej opcji chyba nie ma ?

0

@jan kowal: Tak, tutaj masz rację :) Może być bez parametrów. Konstruktor dałem z parametrami, bo być może chcesz wewnątrz sprawdzić w oparciu o dane pobrane z bazy danych czy wybrany załącznik jest prawidłowy

0
jan kowal napisał(a):
jan kowal napisał(a):

napisz coś więcej jak ma wyglądać ta metoda , bo gonię w piętkę i nie mogę dogonić ?

PlikPDF pdf = PobierzPDF(PlikZamowienia zamowienie);

żeby twój kod miał szansę zadziałać , potrzebuję konstruktor bez parametrów z możliwością ustawienia zmiennych w klasie dziedziczącej . A takiej opcji chyba nie ma ? Jak zauważyłeś metoda PobierzListeZamowien() jest bez parametrów , w takiej sytuacji w jaki sposób mam utworzyć obiekt typu ZamowienieZPlikiemPDF ze zmiennymi jeśli nie przekazuję żadnego parametru . Dodam że pobieram listę w całości bez warunku .

0

ZamowienieZPlikiemPDF to nic innego jak klasa

public class PlikZamowienia : Zamowienie, INotifyPropertyChanged
    {
        public PlikZamowienia(Zamowienie zamowienie) : base(zamowienie)
        {
            PDF = null;
        }
        public PlikZamowienia(Zamowienie zamowienie, PlikPDF plikPDF) : base(zamowienie)
        {
            PDF = plikPDF;
        }

        private PlikPDF pDF = null;
        public PlikPDF PDF
        {
            get
            {
                return pDF;
            }
            set
            {
                pDF = value;
                OnPropertyChanged("PDF");
            }
        }
    }

**PlikZamowienia **dziedziczy właściwości po Zamowienie, więc posiada jego wszystkie właściwości. Ponad to ma dodaną właściwość PlikPDF PDF.
W PobierzPDF(PlikZamowienia zamowienie); możesz wybrać plik i wykonać na nim operacje. Przykładem jest kiedy użytkownik klika na przycisk wybrania załącznika, a załącznik został już wcześniej wybrany:

public PobierzPDF(PlikZamowienia zamowienie)
{
     if(zamowienie.PDF != null)
          MessageBox.Show("Próbujesz nadpisać załącznik");
}
0

Może to nieco rozjaśni sprawę. Manipulujesz tylko listą utworzoną w kodzie. Nie ingerujesz w widok
screenshot-20200228142650.png

private static IEnumerable<PlikPDF> PobierzPDF(PlikZamowienia pz)
        {

            MessageBox.Show(pz.IdZamowienia);
            List<PlikPDF> noweElementy = new List<PlikPDF>();

            OpenFileDialog openFileDialog = new OpenFileDialog();
            openFileDialog.Multiselect = true;
            openFileDialog.Filter = "Text files (*.pdf)|*.pdf|All files (*.*)|*.*";
            openFileDialog.InitialDirectory = Environment.GetFolderPath(Environment.SpecialFolder.MyDocuments);
            if (Convert.ToBoolean(openFileDialog.ShowDialog()) == true)
            {
                foreach (string filename in openFileDialog.FileNames)
                      noweElementy.Add(new PlikPDF(filename));
                return noweElementy;
             }
             else
                  return new PlikPDF[]{};

**PlikZamowienia **będzie wyglądał tak:

public class PlikZamowienia : Zamowienie, INotifyPropertyChanged
    {
        public PlikZamowienia(Zamowienie zamowienie) : base(zamowienie)
        {
            PDF = null;
        }
        
        private IList<PlikPDF> pDF_List = new ObservableCollection<PlikPDF>();
        public IList<PlikPDF> PDF_List)
        {
            get
            {
                return pDF_List ;
            }
            private set
            {
                pDF_List = value;
                OnPropertyChanged("PDF_List");
            }
        }
    }
0

Wiesz co, no niby nie ma błędu a mimo to nie wyświetla wartości w combobox . Jaką zmienną mam właściwie z bindować ? Z pliku PlikPDF , Zamowienia czy ZamowienieZPlikiemPDF. Poza tym to cos dziwnie wygląda bo na sztywno ustawiam wartość pobieraną z bazy
zamowienia.PlikPDF = new PlikPDF("Filename") przypisywaną do listy na początku gdy startuje program i też nie wyświetla tego . Tak jak by było coś z bindingiem ? Dodatkowo nie wiem czy to uwzględniałeś, ale chciałem załącząć listę plików do jednego indeksu a Ty wspominasz coś o nadpisywaniu poprzedników ?

0
jan kowal napisał(a):

Wiesz co, no niby nie ma błędu a mimo to nie wyświetla wartości w combobox . Jaką zmienną mam właściwie z bindować ? Z pliku PlikPDF , Zamowienia czy ZamowienieZPlikiemPDF. Poza tym to cos dziwnie wygląda bo na sztywno ustawiam wartość pobieraną z bazy
zamowienia.PlikPDF = new PlikPDF("Filename") przypisywaną do listy na początku gdy startuje program i też nie wyświetla tego . Tak jak by było coś z bindingiem ? Dodatkowo nie wiem czy to uwzględniałeś, ale chciałem załącząć listę plików do jednego indeksu a Ty wspominasz coś o nadpisywaniu poprzedników ?

Dziękowąć bardzo za załączniki !!!

0

@jan kowal: Opisz mi tekstowo co chcesz osiągnąć w punktach:

  1. Co ma się wczytać do klasy (pokaż szablony klas) podczas uruchamiania aplikacji
  2. Co ma się wczytać po kliknięciu w przycisk i gdzie znajduje sie przycisk

Napiszę Ci wtedy aplikację na wzór i opiszę ją jak wróce do domu

Edit:
jeżeli chodzi o **Combobox **on również w **DataContext **ma klasę **PlikZamowienia **
Wystarczy zbindować ItemsSource

<DataGridComboBoxColumn ItemsSource="{Binding Path="PDF_List"}"/>
0

**c#<DataGridComboBoxColumn ItemsSource="{Binding Path="PDF_List"}"/> Po wklejeniu tego kodu aplikacja działa . Ale comboox nic nie wyświetla. Opisałem problem w pierwszym poście z tego tematu , tam tez jest kod .Reszta nie wiele różni się od tego co mi przesłałeś a w zasadzie w ogóle **

1

Przeanalizuj na spokojnie to i powiedz, jeżeli cokolwiek nie będzie zrozumiałe:
screenshot-20200228172155.png

View - MainWindow.xaml

<Window x:Class="Aplikacja.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Aplikacja"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.DataContext>
            <local:MainWindowViewModel x:Name="hViewModel"/>
        </Grid.DataContext>
        <DataGrid ItemsSource="{Binding Path=OrderElementsCollection}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Path=DataContext.UriCollection, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type DataGrid}}}" 
                                      SelectedItem="{Binding Path=SelectedUri, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
                    
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button x:Name="hGeneratePDF" Content="Generuj PDF" Click="HGeneratePDF_Click"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>

Model - MainWindow.xaml.cs

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Data;
using System.Windows.Documents;
using System.Windows.Input;
using System.Windows.Media;
using System.Windows.Media.Imaging;
using System.Windows.Navigation;
using System.Windows.Shapes;

namespace Aplikacja
{
    /// <summary>
    /// Logika interakcji dla klasy MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();
            
            // Zapisujesz w ViewModelu Zamówienia
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(0, "Zamówienie 0")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(1, "Zamówienie 1")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(2, "Zamówienie 2")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(3, "Zamówienie 3")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(4, "Zamówienie 4")));

            // Zapisujesz w ViewModelu  Pliki
            hViewModel.UriCollection.Add("Plik 1");
            hViewModel.UriCollection.Add("Plik 2");
            hViewModel.UriCollection.Add("Plik 3");
            hViewModel.UriCollection.Add("Plik 4");
        }

        private void HGeneratePDF_Click(object sender, RoutedEventArgs e)
        {
            OrderElement element = (sender as Button).DataContext as OrderElement;
            MessageBox.Show("ID = " + element.ID + Environment.NewLine +
                "Name = " + element.Name + Environment.NewLine +
                "Wybrany plik PDF = " + element.SelectedUri);
        }
    }
}

ViewModel - MainWindowViewModel.cs

using System;
using System.Collections.Generic;
using System.Collections.ObjectModel;
using System.ComponentModel;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace Aplikacja
{
    /// <summary>
    /// Klasa przetrzymująca dane z bazy danych
    /// </summary>
    class Order : INotifyPropertyChanged
    {
        // Poczytaj o PropertyChanged. To bardzo ważne aby Twój widok się odświeżał i odwrotnie
        #region PropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string PropertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }
        #endregion

        public Order(int ID, string Name)
        {
            this.ID = ID;
            this.Name = Name;
        }
        public int ID { get; private set; }
        public string Name { get; private set; }
    }
    /// <summary>
    /// Element listy <see cref="OrderElementsCollection"/> połączony z każdym elementem w DataGridzie. Dziedziczy właściwości po <see cref="Order"/>
    /// </summary>
    class OrderElement : Order, INotifyPropertyChanged
    {
        /// <summary>
        /// Tworzy nowe wystąpienie obiektu
        /// </summary>
        /// <param name="order">Dane zamowienia pobrane z bazy danych</param>
        public OrderElement(Order order) : base(order.ID, order.Name)
        {

        }

        private string selectedUri;
        /// <summary>
        /// Obiekt z Comboboxa wybrany dla każdego elementu
        /// </summary>
        public string SelectedUri
        {
            get
            {
                return selectedUri;
            }
            set
            {
                selectedUri = value;
                OnPropertyChanged("SelectedUri");
            }
        }
        
    }
    class MainWindowViewModel
    {
        public MainWindowViewModel()
        {

        }

        /// <summary>
        /// Kolekcja wszystkich dostępnych załączników
        /// </summary>
        public IList<string> UriCollection { get; private set; } = new ObservableCollection<string>();
        /// <summary>
        /// Kolekcja wszystkich dostępnych zamówień
        /// </summary>
        public IList<OrderElement> OrderElementsCollection { get; private set; } = new ObservableCollection<OrderElement>();
    }
}

0

Wszystko pięknie i nawet działa, ale nie tak jak trzeba . Lista plików powinna być indywidualna dla każdego z wierszy. W zależności od tego jakie pliki zostały załączone. Ten punkt już przerabialiśmy . Jak dla mnie to taka zabawa w kotka i myszkę :)

0

Jeżeli chcesz aby załączniki dla każdego zamówienia były oddzielne to użyj klasy gdzie lista plików jest przechowywana w każdym elemencie:
Order

/// <summary>
    /// Klasa przetrzymująca dane z bazy danych
    /// </summary>
    class Order : INotifyPropertyChanged
    {
        // Poczytaj o PropertyChanged. To bardzo ważne aby Twój widok się odświeżał i odwrotnie
        #region PropertyChanged
        public event PropertyChangedEventHandler PropertyChanged;
        public void OnPropertyChanged(string PropertyName)
        {
            this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(PropertyName));
        }
        #endregion

        public Order(int ID, string Name)
        {
            this.ID = ID;
            this.Name = Name;
        }
        public int ID { get; private set; }
        public string Name { get; private set; }
    }

OrderElement

/// <summary>
    /// Element listy <see cref="OrderElementsCollection"/> połączony z każdym elementem w DataGridzie. Dziedziczy właściwości po <see cref="Order"/>
    /// </summary>
    class OrderElement : Order, INotifyPropertyChanged
    {
        /// <summary>
        /// Tworzy nowe wystąpienie obiektu
        /// </summary>
        /// <param name="order">Dane zamowienia pobrane z bazy danych</param>
        public OrderElement(Order order) : base(order.ID, order.Name)
        {

        }

        private string selectedUri;
        /// <summary>
        /// Obiekt z Comboboxa wybrany dla każdego elementu
        /// </summary>
        public string SelectedUri
        {
            get
            {
                return selectedUri;
            }
            set
            {
                selectedUri = value;
                OnPropertyChanged("SelectedUri");
            }
        }

        /// <summary>
        /// Lista plików dostępnych dla konkretnego elementu
        /// </summary>
        public IList<string> FileUris { get; private set; } = new ObservableCollection<string>();
    }

ViewModel

class MainWindowViewModel
    {
        public MainWindowViewModel()
        {

        }

        /// <summary>
        /// Kolekcja wszystkich dostępnych zamówień
        /// </summary>
        public IList<OrderElement> OrderElementsCollection { get; private set; } = new ObservableCollection<OrderElement>();
    }

Model - Zobacz tutaj jak dodać plik do listy plików konkretnego elementu

namespace Aplikacja
{
    /// <summary>
    /// Logika interakcji dla klasy MainWindow.xaml
    /// </summary>
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            // Zapisujesz w ViewModelu Zamówienia
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(0, "Zamówienie 0")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(1, "Zamówienie 1")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(2, "Zamówienie 2")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(3, "Zamówienie 3")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(4, "Zamówienie 4")));
        }

        private void HGeneratePDF_Click(object sender, RoutedEventArgs e)
        {
            OrderElement element = (sender as Button).DataContext as OrderElement; // pobierz instancję elementu w który kliknąłeś
            MessageBox.Show("ID = " + element.ID + Environment.NewLine +
                "Name = " + element.Name + Environment.NewLine +
                "Wybrany plik PDF = " + element.SelectedUri);

            string Uri = SelectUriFromFile(); //Tutaj pobierz sobie ścieżkę do pliku przez openFileDialog
            element.FileUris.Add(Uri); // Dodaj element do listy plików konkretnego wiersza
        }

    }
}

View (XAML) - Tutaj Combobox w DataContext ma nasz OrderElement, więc ItemsSource bindujemy do Path=FileUris

<Window x:Class="Aplikacja.MainWindow"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
        xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:local="clr-namespace:Aplikacja"
        mc:Ignorable="d"
        Title="MainWindow" Height="450" Width="800">
    <Grid>
        <Grid.DataContext>
            <local:MainWindowViewModel x:Name="hViewModel"/>
        </Grid.DataContext>
        <DataGrid ItemsSource="{Binding Path=OrderElementsCollection}" AutoGenerateColumns="False">
            <DataGrid.Columns>
                <DataGridTextColumn Header="ID" Binding="{Binding ID}"/>
                <DataGridTextColumn Header="Name" Binding="{Binding Name}"/>
                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <ComboBox ItemsSource="{Binding Path=FileUris}" 
                                      SelectedItem="{Binding Path=SelectedUri, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>

                <DataGridTemplateColumn>
                    <DataGridTemplateColumn.CellTemplate>
                        <DataTemplate>
                            <Button x:Name="hGeneratePDF" Content="Generuj PDF" Click="HGeneratePDF_Click"/>
                        </DataTemplate>
                    </DataGridTemplateColumn.CellTemplate>
                </DataGridTemplateColumn>
            </DataGrid.Columns>
        </DataGrid>
    </Grid>
</Window>
0

Dziękować. A jak pobrać wiersz z bazy z listą, gdzieś widziałem że trzeba 2 połączenia utworzyć ?

0

@jan kowal: Nie wiem kompletnie o jaki wiersz z bazy z listą Ci chodzi. Musisz pisać precyzyjnie np.
"jak pobrać listę dostępnych załączników dla wybranego elementu w DataGridzie przy obsłudze zdarzenia SelectionChanged ?"

0

Chodzi o to jak zapisać do bazy danych dany wiersz z datagrida wraz z listą plików i jak pobrać taki wiersz ?

0

Po pierwsze musisz zrozumieć jedna najważniejszą rzecz - Nie dotykaj DataGrida. Odwołuj się do elementów do których bindujesz.
screenshot-20200302132905.png
Spójrz na rysunek:
Twój DataGrid to tylko narzędzie do interakcji i wyświetlania danych. Wszystkie Twoje dane są w MainWindowViewModel.cs

<Grid.DataContext>
            <local:MainWindowViewModel x:Name="hViewModel"/>
</Grid.DataContext>

Twój MainWindowViewModel, gdzie znajduje się lista nosi nazwę hViewModel. Tam masz wszystkie dane które Ciebie interesują i nie musisz grzebać w DataGridzie
Zobacz - tutaj dodaję elementy do listy i automatycznie DataGrid odświeża się, a przecież nic w DataGridzie nie robiłem :)

public MainWindow()
        {
            InitializeComponent();

            // Zapisujesz w ViewModelu Zamówienia
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(0, "Zamówienie 0")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(1, "Zamówienie 1")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(2, "Zamówienie 2")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(3, "Zamówienie 3")));
            hViewModel.OrderElementsCollection.Add(new OrderElement(
                new Order(4, "Zamówienie 4")));
        }
0

** Wszystko cacy tłumaczysz i ja to rozumiem, ale jak zapisać i pobrać wiersz z listą plików do i z bazy danych ?**

0

Ale to zależy do jakiej bazy danych :) bazą danych są papierowe archiwa nawet

0

Mysql, insert i select z załączoną listą plików :)

0

Wystarczą 2 metody:

public IEnumerable<OrderElement> Download();
public void Upload(IEnumerable<OrderElement> Elements);

Poczytaj o MySqlConnection

Jeżeli twój problem opisany w temacie został rozwiązany oznacz odpowiedź jako zaakceptowana. Jeżeli chodzi o połączenie z bazą danych poczytaj. Jeżeli twój kod nie będzie działać załóż nowy temat. Pozdrawiam

0

dzięki wielkie za pomoc. Pozdrawiam

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