Willkommen auf myCSharp.de! Anmelden | kostenlos registrieren
 | Suche | FAQ

Hauptmenü
myCSharp.de
» Startseite
» Forum
» Suche
» Regeln
» Wie poste ich richtig?

Mitglieder
» Liste / Suche
» Wer ist online?

Ressourcen
» FAQ
» Artikel
» C#-Snippets
» Jobbörse
» Microsoft Docs

Team
» Kontakt
» Cookies
» Spenden
» Datenschutz
» Impressum

  • »
  • Community
  • |
  • Diskussionsforum
Binding bei DataGridTemplateColumn
Kriz
myCSharp.de - Member



Dabei seit:
Beiträge: 115

Themenstarter:

Binding bei DataGridTemplateColumn

beantworten | zitieren | melden

Folgendes Problem:
Ich möchte in meinem DataGrid ein DataTemplate für meine Cells benutzen. Nur kann man daran (anscheinend) nicht dynamisch binden. Welche Möglichkeiten gibt es?

ItemSource des DataGrid ist eine ObservableCollection<EmployeeRota>:


class EmployeeRota : BaseViewModel
    {
        private Employee _employee;

        public Employee employee
        {
            get { return _employee; }
            set { _employee = value;
                OnPropertyChanged(nameof(employee));
            }
        }

        private ObservableCollection<Shift> _ListOfShifts;

        public ObservableCollection<Shift> ListOfShifts
        {
            get { return _ListOfShifts; }
            set { _ListOfShifts = value;
                OnPropertyChanged(nameof(ListOfShifts));
            }
        }
}

Das erstellen der Spalten erfolgt dynamisch, da ListOfShifts 1 - x Elemente enthalten kann:


            //Spalte für den Namen erstellen
            DataGridTextColumn NameColumn = new DataGridTextColumn() { Header = "Name" };
            Binding NamebindingExpression = new Binding($"employee.Name") { Mode = BindingMode.OneWay };
            NameColumn.Binding = NamebindingExpression;
            grdRota.Columns.Add(NameColumn);

            //Spalten für die Schichten abhängig der Anzahl der Einträge erstellen
            DataTemplate template = (DataTemplate)grdRota.FindResource("template");
            int MaxColumn = vm.ListOfEmployeeRotas.Max(x => x.ListOfShifts.Count);
            for (int i = 0; i < MaxColumn; i++)
            {                
                DataGridTemplateColumn column = new DataGridTemplateColumn() { Header = vm.StartDate.AddDays(i).ToShortDateString(), CellTemplate = template };
                grdRota.Columns.Add(column);
            }

Das Template ist recht einfach:

                <DataTemplate x:Key="template">
                    <StackPanel Orientation="Horizontal">
                        <TextBlock Text="{Binding Name}" Margin="10"/>
                    </StackPanel>
                </DataTemplate>

Würde ich nun eine DataGridTextColumn statt der DataGridTemplateColumn nutzen, könnte ich mit


                Binding bindingExpression = new Binding($"ListOfShifts[{i}]") { Mode = BindingMode.OneWay };
                column.Binding = bindingExpression;
das gewünschte Ergebnis erhalten, aber DataGridTemplateColumn enthält keine Eigenschaft Binding. Und ich würde gern DataGridTemplateColumn nutzen.

Also zusammen gefasst:
Jede Zelle/Spalte muss dynamisch an den entsprechenden Index einer ObservableCollection gebunden werden.
Mit DataGridTextColumn kein Problem, es muss aber DataGridTemplateColumn benutzt werden.
Ein Bonus wäre auch, wenn ich die Spalten im XAML erstellen könnte und dafür nicht extra im Code-Behind rumwurschteln müsste.

Danke schonmal im Vorraus!
Kriz
private Nachricht | Beiträge des Benutzers
Palladin007
myCSharp.de - Member

Avatar #avatar-4140.png


Dabei seit:
Beiträge: 1.782
Herkunft: Düsseldorf

beantworten | zitieren | melden

Also Du vermisst an der DataGridTemplateColumn eine Binding-Property?

Füge den Bindings im Template doch einfach die Property mit hinzu?
Ansonsten - wenn es sowieso in C#-Code aufgebaut wird - gibt der Column als Template-Inhalt ein ContenControl bindest die Content-Property wie Du es brauchst und dein "richtiges" Template bekommt die ContentTemplate-Property.

Also sowas, nur eben dynamisch:


<DataGridTemplateColumn>
    <DataGridTemplateColumn.CellTemplate>
        <DataTemplate>
            <ContentControl Content="{Binding ...}">
              <ContentControl.ContentTemplate>
                  <DataTemplate>
                      </TextBlock Text="{Binding Name}" Margin="10"/>
                  </DataTemplate>
              </ContentControl.ContentTemplate>
            </ContentControl>
        </DataTemplate>
    </DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>

Oder - wenn das Margin das Ziel ist - Du nutzt DataGridTextColumn.ElementStyle und definierst das Margin als Style.
private Nachricht | Beiträge des Benutzers
Kriz
myCSharp.de - Member



Dabei seit:
Beiträge: 115

Themenstarter:

beantworten | zitieren | melden

Jein, mir fehlt die Möglichkeit dynamisch an die Propertys zu binden.

Ich kann bei einer DataGridTextColumn dynamisch an jeden Index meiner ObservableCollection binden, bei einer DataGridTemplateColumn leider nicht. Da kann ich nur die gesamte ObservableCollection dran binden, das bringt mir aber nichts.


for (int i = 0; i < MaxColumn; i++)
{
    DataGridTemplateColumn column = new DataGridTemplateColumn() { Header = vm.StartDate.AddDays(i).ToShortDateString(), CellTemplate = template };
    grdRota.Columns.Add(column);
}
Mit diesem Code ist der DataContext jeder Spalte die gesamte ObservableCollection, ich möchte aber pro Spalte den jeweiligen Index haben.

Ich habe mittlerweile auch DataTables ausprobiert, das fühlt sich aber sehr wie Flickschusterei an.
Dieser Beitrag wurde 1 mal editiert, zum letzten Mal von Kriz am .
private Nachricht | Beiträge des Benutzers
Th69
myCSharp.de - Experte

Avatar #avatar-2578.jpg


Dabei seit:
Beiträge: 4.359

beantworten | zitieren | melden

Vllt. hilft dir eine der Antworten aus WPF - How to bind a DataGridTemplateColumn?
private Nachricht | Beiträge des Benutzers
Kriz
myCSharp.de - Member



Dabei seit:
Beiträge: 115

Themenstarter:

beantworten | zitieren | melden

Th69, danke Dir, aber den Beitrag hatte ich schon mehrfach durchforstet.
private Nachricht | Beiträge des Benutzers