Wie in
diesem Thread geplant habe ich ein Control in WPF und C# programmiert, das es ermöglicht Elemente in einer Matrix darzustellen. Dabei sollten die ColumnHeader auf der Unterseite dargestellt werden und die Header allgemein immer sichtbar sein. In Excel heißt dieses Verhalten "fixierte Spalte/Zeile".
Damit ihr auch davon etwas habt schicke ich euch im Anhang den Code. Das Control befindet sich im Namespace
Matrix.
Ich erlaube hiermit ausdrücklich die Weiterverwendung und Veränderung des Controls. Anpassungen, Ideen, Vorschläge und Umsetzungen, die alle interessieren könnten, sollen in diesem Thread geteilt werden.
Die Verwendung ist ziemlich einfach, ich mache einfach mal ein Codebeispiel:
|
Quellcode
|
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
|
<m:MatrixControl ColumnHeaderHeight="150"
ColumnHeadersSource="{Binding Controller.ColumnHeaders}"
ColumnWidth="50"
ElementsSource="{Binding Controller.MatrixElements}"
RowHeaderWidth="150"
RowHeadersSource="{Binding Controller.RowHeaders}"
RowHeight="50">
<m:MatrixControl.RowHeaderTemplate>
<DataTemplate>
<Label>
<Label.Background>
<SolidColorBrush Color="{Binding Hue}" />
</Label.Background>
<StackPanel>
<TextBlock Text="{Binding Description}" />
<TextBlock Text="{Binding PinName}" />
</StackPanel>
</Label>
</DataTemplate>
</m:MatrixControl.RowHeaderTemplate>
<m:MatrixControl.ColumnHeaderTemplate>
<DataTemplate>
<Label>
<Label.Background>
<SolidColorBrush Color="{Binding Hue}" />
</Label.Background>
<Label.LayoutTransform>
<RotateTransform Angle="90" />
</Label.LayoutTransform>
<StackPanel>
<TextBlock Text="{Binding Description}" />
<TextBlock Text="{Binding PinName}" />
</StackPanel>
</Label>
</DataTemplate>
</m:MatrixControl.ColumnHeaderTemplate>
<m:MatrixControl.ElementTemplate>
<DataTemplate>
<Label Grid.Row="{Binding Row}" Grid.Column="{Binding Column}">
<CheckBox IsChecked="{Binding IsConnected, Mode=TwoWay}" />
</Label>
</DataTemplate>
</m:MatrixControl.ElementTemplate>
</m:MatrixControl>
|
Ich habe versucht mich an die .NET Namenskonventionen zu halten, damit die Eigenschaften selbsterklärend sind. Die drei ObservableCollections an die gebunden wird, beinhalten ViewModels, die die entsprechenden Bindungen an ihre Eigenschaften ermöglichen. Die Rows und Columns werden dynamisch je nach Länge der RowHeader und ColumnHeader Collections erzeugt. Damit eine Positionierung der Elemente in der Matrix funktioniert, muss im DataTemplate das erste Kind-Element die Attached-Properties
Grid.Row und
Grid.Column setzen oder an diese binden. Ansonsten wird Grid und/oder Row auf 0 festgelegt. Im Screenshot ist zu sehen was der Code oben bewirkt.
Meine Ideen, die ich oder ihr umsetzen könnt sind:
- Postionierung der Header kann eingestellt werden. (Oben/Unten, Links/Rechts)
- Horizontales Scrollen mit der Maus über ein kippbares Mausrad oder so. Hier oder hier wäre ein Vorschlag wie man das machen könnte.
- Scrollen über Touchgesten. Funktioniert eventuell schon, wenn PanningMode=true gesetzt wird. Kann das jemand mit einem Tablet mal ausprobieren?
- Grid.RowSpan und Grid.ColumnSpan werden unterstützt. Kann sein, dass das genauso wie bei Grid.Row und Grid.Column gelöst werden kann. Müsste mal jemand ausprobieren - ich hatte noch keinen Bedarf dafür.