Du bist nicht angemeldet.

Stilllegung des Forums
Das Forum wurde am 05.06.2023 nach über 20 Jahren stillgelegt (weitere Informationen und ein kleiner Rückblick).
Registrierungen, Anmeldungen und Postings sind nicht mehr möglich. Öffentliche Inhalte sind weiterhin zugänglich.
Das Team von spieleprogrammierer.de bedankt sich bei der Community für die vielen schönen Jahre.
Wenn du eine deutschsprachige Spieleentwickler-Community suchst, schau doch mal im Discord und auf ZFX vorbei!

Werbeanzeige

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

1

10.05.2016, 23:22

[WPF C#] Datagrid: Fixierte Colums/Rows, Columnheader an Unterseite anzeigen

Hallo Leute,

wie im Titel beschrieben brauche ich ein Datagrid oder eine andere matrixähnliche Darstellung, mit den folgenden Anforderungen:
  1. Wenn gescrollt wird (beide Richtungen), dann sollen die Beschriftungen für Zeilen und Spalten mitscrollen, aber immer sichbar sein (nennt sich "fixiert" bei Excel)
  2. Das Scrollen kann in Zeilenschritten passieren, aber darf auf keinen Fall sprunghaft geschehen, sondern soll flüssig sein
  3. Die Titelbeschriftungen sollen an der Unterkante angezeigt werden
  4. Eine automatische oder manuelle Sortierfunktion der Zeilen und Spalten wird nicht benötigt
  5. Als Daten kommen nur Wahrheitswerte vor, die über eine Checkbox geändert werden sollen
  6. Die Zeilenheader sind ein zweizeiliger Text mit unterschiedlicher Farbe hinterlegt
  7. Die Spaltenheader sind ein zweizeiliger vertikaler (oder schräger) Text mit unterschiedlicher Farbe hinterlegt
Meinen Nachforschungen zur Folge kann ich ein Datagrid oder -view nicht verwenden, weil es die Positionierung der Kopfzeile am unteren Ende nicht zulässt und nicht flüssig scrollbar ist. Außerdem macht ein schräger Spaltenheader die Spalten breiter - das ist unerwünscht. Nun bin ich am überlegen, das mit einem normalen Grid und MVVM zu machen, indem ich per Programmcode Zeilen-, Spaltendefinitionen und ViewModels generiere und diesen Positionen im Grid zuweise. Einziger Haken an dieser Variante ist, dass ich keinen Plan habe, wie ich die Fixierung der Zeilen- und Spaltenbeschriftung programmiere.

Ich habe nichts gegen .NET-Fremde Steuerelemente, aber würde gerne wenns geht ein eigenes programmieren. :) Schonmal danke für alle hilfreichen Fragen und Antworten!
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

Schorsch

Supermoderator

Beiträge: 5 145

Wohnort: Wickede

Beruf: Softwareentwickler

  • Private Nachricht senden

2

11.05.2016, 00:34

Ich habe nichts gegen .NET-Fremde Steuerelemente, aber würde gerne wenns geht ein eigenes programmieren.

Dann mach das doch. Ich kann in deinem Beitrag keine Frage finden. Hast du es schon versucht und kommst nicht weiter? Falls ja, was klappt und was klappt nicht? Lass dir nicht alles aus der Nase ziehen;)
„Es ist doch so. Zwei und zwei macht irgendwas, und vier und vier macht irgendwas. Leider nicht dasselbe, dann wär's leicht.
Das ist aber auch schon höhere Mathematik.“

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

3

11.05.2016, 08:19

Erstmal weiß ich au eigener Erfahrung (durch ein Kundenprojekt), dass ein eigenes DataGrid in WPF teuflisch zu implementieren ist. Lass die Finger davon!

"1. Wenn gescrollt wird (beide Richtungen), dann sollen die Beschriftungen für Zeilen und Spalten mitscrollen, aber immer sichbar sein (nennt sich "fixiert" bei Excel)"

Das können die WPF DataGrid selbst nicht von Hause aus. Allerdings habe ich folgendes gefunden: FrozenColumns

Ansonsten wäre der richtige Weg: Suche dir ein WPF-Control, was das kann. Ich erinnere mich, dass das von Exceed das kann.


"2. Das Scrollen kann in Zeilenschritten passieren, aber darf auf keinen Fall sprunghaft geschehen, sondern soll flüssig sein"

Das geht denke ich, dazu muss man den ScrollMode auf Pixel stellen und dann beim Scrollevent per Hand zur nächsten Zeile Scrollen, vielleicht geht das mit einem Storyboard.

"3. Die Titelbeschriftungen sollen an der Unterkante angezeigt werden"

Controltemplate überschreiben, wenn du die Überschriften unten am Grid haben willst. Wenn du nur den Text innerhalb der Header vertikal nach unten ausgerichtet haben willst, dann das HeaderTemplate überschreiben.

"4. Eine automatische oder manuelle Sortierfunktion der Zeilen und Spalten wird nicht benötigt"

Dann deaktiviere das Sortieren.

"5. Als Daten kommen nur Wahrheitswerte vor, die über eine Checkbox geändert werden sollen"

CellTemplate überschreiben oder direkt DataGridBoolColumn anlegen.

"6. Die Zeilenheader sind ein zweizeiliger Text mit unterschiedlicher Farbe hinterlegt"

Style der Header überschreiben. Der Text zweizeilig sollte auch über ein DataTemplate gehen.

"7. Die Spaltenheader sind ein zweizeiliger vertikaler (oder schräger) Text mit unterschiedlicher Farbe hinterlegt"

Ebenfalls wie 6.

Hoffe, das hilft dir weiter. Ist nicht ganz so trivial dieses Thema.

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

4

11.05.2016, 20:24

Das können die WPF DataGrid selbst nicht von Hause aus. Allerdings habe ich folgendes gefunden: FrozenColumns
Danke, das wusste ich nicht! Dann müsste ich die erste Spalte als Beschriftungsspalte für die Zeilen verwenden?

Das geht denke ich, dazu muss man den ScrollMode auf Pixel stellen und dann beim Scrollevent per Hand zur nächsten Zeile Scrollen, vielleicht geht das mit einem Storyboard.
Habe noch nie mit einem Storyboard gearbeitet... Finde ich aber raus, wenn ich mich für ein DataGrid entscheide.

Controltemplate überschreiben, wenn du die Überschriften unten am Grid haben willst. Wenn du nur den Text innerhalb der Header vertikal nach unten ausgerichtet haben willst, dann das HeaderTemplate überschreiben.
Hast du dafür ein Beispiel oder Link? Ich habe noch nie mit Controltemplates gearbeitet und nichts im Netz gefunden, was mir erklärt wie ich damit die Positionen in einem DataGrid ändere.

Die anderen Punkte, die ich angeführt habe, sollen nur ausdrücken, dass es lediglich um ein Layout geht und nicht um komplizierte Funktionen eines DataGrid. Wie ich mit DataTemplates umgehe weiß ich. ;) Danke trotzdem!

Weil es nur um die simple Anzeige von einer Matrix geht, bin ich der Meinung, dass sich das auch selbst programmieren lässt. Außerdem benötige ich keine Datenbindung, weil die Daten in einer Art vorliegen, die das DataGrid sowieso nicht direkt frisst - komplexe Umwandlung nötig. Da ich meine Fragen anscheinend zu versteckt gestellt habe, nun (hoffentlich deutlicher): Meine Idee ist, ein simples Grid zu erstellen und mit ganz vielen ViewModels als Childs zu füllen. Es gibt ViewModels für Spaltentitel, Zeilentitel und die Matrixeinträge. Über 3 verschiedene DataTemplates werden diese Informationen sichtbar gemacht.

Wie sorge ich dafür, dass die DataTemplates als Matrix angeordnet werden? Ich kann jedem ViewModel seine X|Y-Position im Grid übergeben und auch die benötigten Row- und Column-Definitions im Grid erzeugen, aber wie kommen diese Zahlen zu den Attached-Properties der DataTemplates. Kann man da Datenbindung einsetzen? Ich stelle mir sowas vor:

C#-Quelltext

1
2
3
4
5
public class GridEntryViewModel
{
    public int Row, Column;
    public string Text;
}

Quellcode

1
2
3
4
5
6
7
<Grid>
    <Grid.Resources>
        <DataTemplate DataType={x:Type GridEntryViewModel} Grid.Row={Binding Row} Grid.Column={Binding Column}>
            <TextBlock Text={Binding Text}/>
        </DataTemplate>
    </Grid.Resources>
</Grid>
Hoffe mal, da sind keine groben Fehler drin - hab das grad so aus dem Kopf runtergeschrieben. ^^

Meine andere Frage: Wie sorge ich dafür, dass die Titel der Zeilen und Spalten fest bleiben? Meine Idee ist, zwei scrollbare Stackpanels zu erstellen, die unten und links an das oben beschriebene Grid angrenzen und die Titel enthalten. Die Scrollposition dieser Panels müssten dann an die jeweilige Scrollposition des Grids gebunden sein, damit alles mitscrollt. Außerdem dürfen nur in dem Grid die Scrollbars sichtbar sein, sonst hab ich ja 4 Scrollbars sichtbar - das sieht doof aus. Ich mache mal ein Beispiel, wie ich mir das vorstelle:

Quellcode

1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
<Grid>
    <Grid.RowDefinitions>
        <RowDefinition/>
        <RowDefinition/>
    </Grid.RowDefinitions>
    <Grid.ColumnDefinitions>
        <ColumnDefinition/>
        <ColumnDefinition/>
    </Grid.ColumnDefinitions>
    <ScrollViewer Grid.Row="1" Grid.Column="0" ScrollbarsVisible="false" VerticalScrollPosition="{Binding ElementName=Matrix, Path=VerticalScrollPosition, Mode=TwoWay}">
        <!-- Hier stehen die Zeilenüberschriften drin -->
    </ScrollViewer>
    <ScrollViewer Grid.Row="0" Grid.Column="1" ScrollbarsVisible="false" HorizontalScrollPosition="{Binding ElementName=Matrix, Path=HorizontalScrollPosition, Mode=TwoWay}">
        <!-- Hier stehen die Spaltenüberschriften drin -->
    </ScrollViewer>
    <ScrollViewer x:Name="Matrix" Grid.Row="1" Grid.Column="0">
        <Grid>
            <!-- Hier stehen die Matrixeinträge drin - in meinem Fall also die ganzen CheckBoxen - wie im Beispiel oben -->
        </Grid>
    </ScrollViewer>
</Grid>
Auch das Beispiel soll nur verdeutlichen, was ich für eine Idee habe! Die Eigenschaftennamen gibts so nicht glaub ich.
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

5

15.05.2016, 11:33

Können wir nochmal kurz einen Schritt zurückmachen? Ich glaube, du hast kein Datagrid, wenn jeder Wert in einem XY-Gitter liegt, das ist dann tatsächlich eine Matrix! DataGrids stellen ja Zeilenweise Informationen dar.

Wenn dies der Fall ist, dann muss ich meine Aussage nochmal deutlich anpassen ;) Kannst du vielleicht mal zur Verdeutlichung ein Bild machen?

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

6

15.05.2016, 18:15

OK, dann haben wir definitiv kein DataGrid, sondern eine Matrix. Am Ende dieses Posts habe ich ein Bild gepostet. So sieht es im Augenblick aus. Ich habe mal gegoogelt, wie man ein ItemsControl mit einem Grid vernünftig verbinden kann und mich schließlich für diese Methode entschieden. Wenn ihr noch eine einfachere Möglichkeit kennt, dann rückt raus! ;)
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

TrommlBomml

Community-Fossil

Beiträge: 2 117

Wohnort: Berlin

Beruf: Software-Entwickler

  • Private Nachricht senden

7

18.05.2016, 09:08

Ich glaube das geht so in die Richtung, wie es klappen könnte. Ein Grid und die Attached-Property über Binding setzen wäre auch mein erster Ansatz gewesen. Ich bin auf das Ergebnis gespannt!

CeDoMain

Alter Hase

  • »CeDoMain« ist der Autor dieses Themas

Beiträge: 587

Wohnort: Ilmenau

Beruf: Student für Mechatronik

  • Private Nachricht senden

8

23.05.2016, 21:32

Hier habe für mein Matrix-Control einen eigenen Thread erstellt. :)
Mit freundlichem Gruß
CeDo
Discord: #6996 | Skype: cedomain

Lass solche persönlichen Angriffe lieber bleiben, meine sind härter.

Werbeanzeige