Versuche und Ergebnisse Umstrukturiert

This commit is contained in:
2026-02-19 20:16:26 +01:00
parent a5d2f5490c
commit 9b95958eeb
108 changed files with 1427 additions and 7786 deletions

View File

@@ -0,0 +1,834 @@
# c-entron.NET - XAML View Templates für Asset Management & Scheduling
> **Generiert**: 2025-11-11
> **Zweck**: Production-ready XAML View Templates für neue Module
> **Pattern**: DevExpress Controls, Master-Detail Layout, Binding Best Practices
---
## 📋 Inhaltsverzeichnis
1. [Asset Management Views](#asset-management-xaml-views)
- [Geräte-Inventarverwaltung](#161-assetinventoryviewxaml)
- [Patch-Management](#162-patchmanagementviewxaml)
- [SNMP-Monitoring](#163-snmpmonitoringviewxaml)
- [Lizenz-Verwaltung](#164-licensemanagementviewxaml)
- [Compliance Dashboard](#165-compliancedashboardviewxaml)
2. [Scheduling Views](#scheduling-xaml-views)
- [Termine & Buchungen](#171-appointmentmanagementviewxaml)
- [Route-Optimierung](#172-routeoptimizationviewxaml)
- [Kapazitätsplanung](#173-capacityplanningviewxaml)
- [SLA-Management](#174-slamanagementviewxaml)
---
# ASSET MANAGEMENT XAML VIEWS
## 16.1 AssetInventoryView.xaml
**Pfad**: `src/centron/Centron.WPF.UI/Modules/Administration/AssetManagement/AssetInventoryView.xaml`
**Pattern**: Master-Detail Layout mit Filter-Sektion
- Linkes Panel: Geräte-Liste (GridControl)
- Rechtes Panel: Detail-Form
- Oben: Filter-Sektion (collapsible)
```xaml
<?xml version="1.0" encoding="utf-8"?>
<controls:BaseModule
xmlns:controls="clr-namespace:CentronSoftware.Centron.WPF.UI.Extension.Controls;assembly=Centron.WPF.UI.Extension"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/expression/blend/2008"
x:Class="CentronSoftware.Centron.WPF.UI.Modules.Administration.AssetManagement.AssetInventoryView"
Background="{DynamicResource {x:Static SystemColors.ControlBrushKey}}">
<!-- FILTER SECTION -->
<dxlc:LayoutControl Orientation="Vertical">
<!-- Filter Header -->
<dxlc:LayoutGroup
IsCollapsible="True"
Caption="{x:Static properties:LocalizedStrings.Filter}"
Visibility="{Binding UISettings.ShowFilter, Converter={StaticResource BoolToVisibilityConverter}}">
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Suchtext}">
<dxe:ButtonEdit
EditValue="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}"
NullValueButtonPlacement="EditBox"
Width="250" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Gerättyp}">
<dxe:ComboBoxEdit
ItemsSource="{Binding DeviceTypes}"
DisplayMember="Description"
SelectedItem="{Binding SelectedDeviceType}"
Width="250" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Abteilung}">
<dxe:ComboBoxEdit
ItemsSource="{Binding Departments}"
DisplayMember="DepartmentName"
SelectedItem="{Binding SelectedDepartment}"
Width="250" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Status}">
<dxe:ComboBoxEdit
ItemsSource="{Binding Statuses}"
DisplayMember="StatusText"
SelectedItem="{Binding SelectedStatus}"
Width="250" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="">
<dx:SimpleButton
Content="{x:Static properties:LocalizedStrings.Filter_Löschen}"
Command="{Binding ClearFiltersCommand}"
Width="100" />
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
<!-- MASTER-DETAIL LAYOUT -->
<dxlc:LayoutControl Orientation="Horizontal">
<!-- LEFT PANEL: Device List -->
<dxlc:LayoutItem Width="350" AllowHorizontalSizing="True" Caption="Geräte">
<dxg:GridControl
ItemsSource="{Binding Assets}"
SelectedItem="{Binding SelectedAsset}"
MaxHeight="600">
<dxg:GridControl.View>
<dxg:TableView
UseEvenRowBackground="True"
EnableImmediatePosting="True"
ShowColumnHeaders="True" />
</dxg:GridControl.View>
<dxg:GridColumn
FieldName="AssetTag"
Header="{x:Static properties:LocalizedStrings.AssetTag}"
Width="80" />
<dxg:GridColumn
FieldName="DeviceName"
Header="{x:Static properties:LocalizedStrings.Gerätname}"
Width="150" />
<dxg:GridColumn
FieldName="DeviceTypeName"
Header="{x:Static properties:LocalizedStrings.Typ}"
Width="80" />
<dxg:GridColumn
FieldName="StatusName"
Header="{x:Static properties:LocalizedStrings.Status}"
Width="70" />
</dxg:GridControl>
</dxlc:LayoutItem>
<!-- RIGHT PANEL: Detail Form -->
<dxlc:LayoutControl Orientation="Vertical" Width="*">
<!-- Detail Header -->
<dxlc:LayoutGroup Caption="{x:Static properties:LocalizedStrings.Gerätdetails}">
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Gerätname}">
<dxe:TextEdit
Text="{Binding SelectedAsset.DeviceName, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.AssetTag}">
<dxe:TextEdit
Text="{Binding SelectedAsset.AssetTag}"
ReadOnly="True"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Seriennummer}">
<dxe:TextEdit
Text="{Binding SelectedAsset.SerialNumber, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Gerättyp}">
<dxe:ComboBoxEdit
ItemsSource="{Binding DeviceTypes}"
DisplayMember="Description"
SelectedItem="{Binding SelectedAsset.DeviceType, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Hersteller}">
<dxe:TextEdit
Text="{Binding SelectedAsset.Manufacturer, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Modell}">
<dxe:TextEdit
Text="{Binding SelectedAsset.ModelNumber, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
<!-- Assignment & Status -->
<dxlc:LayoutGroup Caption="{x:Static properties:LocalizedStrings.Zuordnung}">
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Abteilung}">
<dxe:ComboBoxEdit
ItemsSource="{Binding Departments}"
DisplayMember="DepartmentName"
SelectedItem="{Binding SelectedAsset.Department, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Standort}">
<dxe:ComboBoxEdit
ItemsSource="{Binding Locations}"
DisplayMember="LocationName"
SelectedItem="{Binding SelectedAsset.Location, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Benutzer}">
<dxe:TextEdit
Text="{Binding SelectedAsset.AssignedUser, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="{x:Static properties:LocalizedStrings.Status}">
<dxe:ComboBoxEdit
ItemsSource="{Binding Statuses}"
DisplayMember="StatusText"
SelectedItem="{Binding SelectedAsset.Status, UpdateSourceTrigger=PropertyChanged}"
Width="300" />
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
<!-- Commands -->
<dxlc:LayoutGroup Orientation="Horizontal" Height="40">
<dx:SimpleButton
Content="{x:Static properties:LocalizedStrings.Neu}"
Command="{Binding CreateNewAssetCommand}"
Width="100" />
<dx:SimpleButton
Content="{x:Static properties:LocalizedStrings.Speichern}"
Command="{Binding SaveAssetCommand}"
Width="100" />
<dx:SimpleButton
Content="{x:Static properties:LocalizedStrings.Löschen}"
Command="{Binding DeleteAssetCommand}"
Width="100" />
<dx:SimpleButton
Content="{x:Static properties:LocalizedStrings.Importieren}"
Command="{Binding ImportBatchCommand}"
Width="100" />
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</dxlc:LayoutControl>
</dxlc:LayoutControl>
</controls:BaseModule>
```
**ViewModel-Binding Summary**:
```
SearchText → Filter TextEdit (updates on PropertyChanged)
SelectedDeviceType → DeviceType ComboBoxEdit
SelectedDepartment → Department ComboBoxEdit
SelectedStatus → Status ComboBoxEdit
ClearFiltersCommand → Filter Clear Button
Assets → GridControl ItemsSource
SelectedAsset → GridControl SelectedItem + Detail Form DataContext
DeviceName → Detail TextEdit
SerialNumber → Detail TextEdit (unique validation)
AssetTag → Detail TextEdit (read-only)
Manufacturer → Detail TextEdit
ModelNumber → Detail TextEdit
CreateNewAssetCommand → [Neu] Button
SaveAssetCommand → [Speichern] Button
DeleteAssetCommand → [Löschen] Button
ImportBatchCommand → [Importieren] Button
```
---
## 16.2 PatchManagementView.xaml
**Pfad**: `src/centron/Centron.WPF.UI/Modules/Administration/AssetManagement/PatchManagementView.xaml`
**Pattern**: Tab-based interface with Grid + Detail View
```xaml
<?xml version="1.0" encoding="utf-8"?>
<controls:BaseModule
xmlns:controls="clr-namespace:CentronSoftware.Centron.WPF.UI.Extension.Controls;assembly=Centron.WPF.UI.Extension"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/expression/blend/2008"
x:Class="CentronSoftware.Centron.WPF.UI.Modules.Administration.AssetManagement.PatchManagementView">
<dxlc:LayoutControl Orientation="Vertical">
<!-- Tab Control -->
<TabControl>
<!-- TAB 1: Patch Management -->
<TabItem Header="{x:Static properties:LocalizedStrings.PatchVerwaltung}">
<dxlc:LayoutControl Orientation="Horizontal">
<!-- Left: Patch List -->
<dxlc:LayoutItem Width="400" AllowHorizontalSizing="True" Caption="Verfügbare Patches">
<dxg:GridControl
ItemsSource="{Binding AvailablePatches}"
SelectedItem="{Binding SelectedPatch}">
<dxg:GridColumn FieldName="PatchId" Header="Patch ID" Width="80" />
<dxg:GridColumn FieldName="PatchName" Header="Name" Width="150" />
<dxg:GridColumn FieldName="ReleaseDate" Header="Veröffentlichungsdatum" Width="100" />
<dxg:GridColumn FieldName="Category" Header="Kategorie" Width="80" />
<dxg:GridColumn FieldName="Severity" Header="Kritikalität" Width="80" />
</dxg:GridControl>
</dxlc:LayoutItem>
<!-- Right: Patch Details -->
<dxlc:LayoutControl Orientation="Vertical" Width="*">
<dxlc:LayoutGroup Caption="Patch-Details">
<dxlc:LayoutItem Label="Patch Name">
<dxe:TextEdit Text="{Binding SelectedPatch.PatchName}" ReadOnly="True" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Beschreibung">
<dxe:MemoEdit Text="{Binding SelectedPatch.Description}" Height="100" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Kritikalität">
<dxe:ComboBoxEdit
ItemsSource="{Binding Severities}"
DisplayMember="SeverityName"
SelectedItem="{Binding SelectedPatch.Severity}" />
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
<!-- Target Devices Grid -->
<dxlc:LayoutGroup Caption="Zielgeräte">
<dxg:GridControl
ItemsSource="{Binding TargetDevices}"
MaxHeight="200">
<dxg:GridColumn FieldName="DeviceName" Header="Gerätname" Width="150" />
<dxg:GridColumn FieldName="StatusName" Header="Status" Width="80" />
<dxg:GridColumn FieldName="DeploymentDate" Header="Bereitstellungsdatum" Width="100" />
</dxg:GridControl>
</dxlc:LayoutGroup>
<!-- Commands -->
<dxlc:LayoutGroup Orientation="Horizontal" Height="40">
<dx:SimpleButton Content="Bereitstellen" Command="{Binding DeployPatchCommand}" Width="120" />
<dx:SimpleButton Content="Zurückrollen" Command="{Binding RollbackPatchCommand}" Width="120" />
<dx:SimpleButton Content="Status aktualisieren" Command="{Binding RefreshStatusCommand}" Width="150" />
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</dxlc:LayoutControl>
</TabItem>
<!-- TAB 2: Deployment Campaigns -->
<TabItem Header="Kampagnen">
<dxg:GridControl ItemsSource="{Binding DeploymentCampaigns}">
<dxg:GridColumn FieldName="CampaignName" Header="Name" Width="200" />
<dxg:GridColumn FieldName="StartDate" Header="Startdatum" Width="100" />
<dxg:GridColumn FieldName="EndDate" Header="Enddatum" Width="100" />
<dxg:GridColumn FieldName="CompletionPercentage" Header="Fortschritt %" Width="80" />
<dxg:GridColumn FieldName="StatusName" Header="Status" Width="80" />
</dxg:GridControl>
</TabItem>
</TabControl>
</dxlc:LayoutControl>
</controls:BaseModule>
```
---
## 16.3 SNMPMonitoringView.xaml
**Pfad**: `src/centron/Centron.WPF.UI/Modules/Administration/AssetManagement/SNMPMonitoringView.xaml`
**Pattern**: Real-time Dashboard with Charts
```xaml
<?xml version="1.0" encoding="utf-8"?>
<controls:BaseModule
xmlns:controls="clr-namespace:CentronSoftware.Centron.WPF.UI.Extension.Controls;assembly=Centron.WPF.UI.Extension"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/expression/blend/2008"
x:Class="CentronSoftware.Centron.WPF.UI.Modules.Administration.AssetManagement.SNMPMonitoringView">
<dxlc:LayoutControl Orientation="Vertical">
<!-- Header: Device Selection -->
<dxlc:LayoutGroup Caption="Netzwerk-Geräte" Orientation="Horizontal">
<dxlc:LayoutItem Label="Gerät auswählen">
<dxe:ComboBoxEdit
ItemsSource="{Binding MonitoredDevices}"
DisplayMember="DeviceName"
SelectedItem="{Binding SelectedMonitoredDevice}"
Width="250" />
</dxlc:LayoutItem>
<dx:SimpleButton Content="Aktualisieren" Command="{Binding RefreshMetricsCommand}" Width="100" />
<dx:SimpleButton Content="Alle überwachen" Command="{Binding MonitorAllCommand}" Width="120" />
</dxlc:LayoutGroup>
<!-- Real-time Metrics Dashboard -->
<dxlc:LayoutControl Orientation="Horizontal">
<!-- Left: Metric Cards -->
<dxlc:LayoutControl Orientation="Vertical" Width="250">
<dxlc:LayoutGroup Caption="CPU-Auslastung">
<ProgressBar Value="{Binding CPUUsagePercentage}" Height="30" />
<TextBlock Text="{Binding CPUUsageText}" FontSize="14" FontWeight="Bold" />
</dxlc:LayoutGroup>
<dxlc:LayoutGroup Caption="Speichernutzung">
<ProgressBar Value="{Binding MemoryUsagePercentage}" Height="30" />
<TextBlock Text="{Binding MemoryUsageText}" />
</dxlc:LayoutGroup>
<dxlc:LayoutGroup Caption="Netzwerk-Status">
<TextBlock Text="{Binding NetworkStatusText}" Foreground="{Binding NetworkStatusColor}" />
</dxlc:LayoutGroup>
<dxlc:LayoutGroup Caption="Letztes Update">
<TextBlock Text="{Binding LastUpdateTime}" FontSize="12" />
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
<!-- Right: Charts -->
<dxlc:LayoutControl Orientation="Vertical" Width="*">
<dxc:ChartControl
DataSource="{Binding CPUHistoryData}"
Height="200">
<dxc:XyDiagram2D>
<dxc:LineSeries DisplayName="CPU %"
ArgumentDataMember="Timestamp"
ValueDataMember="CPUPercent" />
</dxc:XyDiagram2D>
</dxc:ChartControl>
<dxc:ChartControl
DataSource="{Binding MemoryHistoryData}"
Height="200">
<dxc:XyDiagram2D>
<dxc:LineSeries DisplayName="Memory %"
ArgumentDataMember="Timestamp"
ValueDataMember="MemoryPercent" />
</dxc:XyDiagram2D>
</dxc:ChartControl>
</dxlc:LayoutControl>
</dxlc:LayoutControl>
<!-- Alerts Grid -->
<dxlc:LayoutGroup Caption="Warnungen & Anomalien">
<dxg:GridControl ItemsSource="{Binding Alerts}" MaxHeight="150">
<dxg:GridColumn FieldName="AlertId" Header="Alert ID" Width="60" />
<dxg:GridColumn FieldName="DeviceName" Header="Gerät" Width="120" />
<dxg:GridColumn FieldName="AlertMessage" Header="Meldung" Width="250" />
<dxg:GridColumn FieldName="SeverityName" Header="Schweregrad" Width="80" />
<dxg:GridColumn FieldName="CreatedDate" Header="Zeit" Width="120" />
</dxg:GridControl>
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</controls:BaseModule>
```
---
## 16.4 LicenseManagementView.xaml
**Pfad**: `src/centron/Centron.WPF.UI/Modules/Administration/AssetManagement/LicenseManagementView.xaml`
```xaml
<?xml version="1.0" encoding="utf-8"?>
<controls:BaseModule
xmlns:controls="clr-namespace:CentronSoftware.Centron.WPF.UI.Extension.Controls;assembly=Centron.WPF.UI.Extension"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/expression/blend/2008"
x:Class="CentronSoftware.Centron.WPF.UI.Modules.Administration.AssetManagement.LicenseManagementView">
<dxlc:LayoutControl Orientation="Vertical">
<!-- Summary Cards -->
<dxlc:LayoutControl Orientation="Horizontal" Height="80">
<Border Background="#FFEAEAEA" Padding="10" CornerRadius="5" Margin="5">
<StackPanel>
<TextBlock Text="Aktive Lizenzen" FontSize="14" FontWeight="Bold" />
<TextBlock Text="{Binding ActiveLicenseCount}" FontSize="20" Foreground="Green" />
</StackPanel>
</Border>
<Border Background="#FFFFCCCC" Padding="10" CornerRadius="5" Margin="5">
<StackPanel>
<TextBlock Text="Ablaufende Lizenzen" FontSize="14" FontWeight="Bold" />
<TextBlock Text="{Binding ExpiringLicenseCount}" FontSize="20" Foreground="Orange" />
</StackPanel>
</Border>
<Border Background="#FFCCCCFF" Padding="10" CornerRadius="5" Margin="5">
<StackPanel>
<TextBlock Text="Ausstehende Lizenzen" FontSize="14" FontWeight="Bold" />
<TextBlock Text="{Binding PendingLicenseCount}" FontSize="20" />
</StackPanel>
</Border>
</dxlc:LayoutControl>
<!-- License Grid -->
<dxlc:LayoutGroup Caption="Lizenz-Verwaltung">
<dxg:GridControl
ItemsSource="{Binding Licenses}"
SelectedItem="{Binding SelectedLicense}">
<dxg:GridColumn FieldName="LicenseKey" Header="Lizenz-Schlüssel" Width="150" />
<dxg:GridColumn FieldName="SoftwareName" Header="Software" Width="120" />
<dxg:GridColumn FieldName="LicenseType" Header="Typ" Width="80" />
<dxg:GridColumn FieldName="PurchaseDate" Header="Kaufdatum" Width="90" />
<dxg:GridColumn FieldName="ExpirationDate" Header="Ablaufdatum" Width="90" />
<dxg:GridColumn FieldName="AssignedDeviceCount" Header="Zugeordnete Geräte" Width="80" />
<dxg:GridColumn FieldName="StatusName" Header="Status" Width="80" />
</dxg:GridControl>
</dxlc:LayoutGroup>
<!-- License Details -->
<dxlc:LayoutGroup Caption="Lizenz-Details" Visibility="{Binding SelectedLicense, Converter={StaticResource NullToVisibilityConverter}}">
<dxlc:LayoutItem Label="Software">
<dxe:TextEdit Text="{Binding SelectedLicense.SoftwareName}" ReadOnly="True" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Lizenz-Typ">
<dxe:ComboBoxEdit
ItemsSource="{Binding LicenseTypes}"
DisplayMember="TypeName"
SelectedItem="{Binding SelectedLicense.LicenseType}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Ablaufdatum">
<dxe:DateEdit SelectedDate="{Binding SelectedLicense.ExpirationDate}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Zugeordnete Geräte">
<dxg:GridControl ItemsSource="{Binding SelectedLicense.AssignedDevices}" MaxHeight="150">
<dxg:GridColumn FieldName="DeviceName" Header="Gerätname" Width="150" />
<dxg:GridColumn FieldName="LicenseKey" Header="Lizenz-Schlüssel" Width="150" />
</dxg:GridControl>
</dxlc:LayoutItem>
<dxlc:LayoutGroup Orientation="Horizontal" Height="40">
<dx:SimpleButton Content="Speichern" Command="{Binding SaveLicenseCommand}" Width="100" />
<dx:SimpleButton Content="Verlängern" Command="{Binding RenewLicenseCommand}" Width="100" />
<dx:SimpleButton Content="Löschen" Command="{Binding DeleteLicenseCommand}" Width="100" />
</dxlc:LayoutGroup>
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</controls:BaseModule>
```
---
## 16.5 ComplianceDashboardView.xaml
**Pfad**: `src/centron/Centron.WPF.UI/Modules/Administration/AssetManagement/ComplianceDashboardView.xaml`
```xaml
<?xml version="1.0" encoding="utf-8"?>
<controls:BaseModule
xmlns:controls="clr-namespace:CentronSoftware.Centron.WPF.UI.Extension.Controls;assembly=Centron.WPF.UI.Extension"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxc="http://schemas.devexpress.com/winfx/2008/xaml/charts"
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/expression/blend/2008"
x:Class="CentronSoftware.Centron.WPF.UI.Modules.Administration.AssetManagement.ComplianceDashboardView">
<dxlc:LayoutControl Orientation="Vertical">
<!-- Compliance Score -->
<dxlc:LayoutGroup Caption="Compliance-Status" Orientation="Horizontal">
<Border Background="{Binding ComplianceScoreColor}" Padding="20" CornerRadius="10" Margin="10" Width="200">
<StackPanel VerticalAlignment="Center">
<TextBlock Text="Compliance Score" FontSize="12" FontWeight="Bold" Foreground="White" />
<TextBlock Text="{Binding ComplianceScorePercentage, StringFormat='{0:P0}'}"
FontSize="32" FontWeight="Bold" Foreground="White" />
<TextBlock Text="{Binding ComplianceScoreStatus}" FontSize="11" Foreground="White" />
</StackPanel>
</Border>
<!-- Audit Status -->
<dxlc:LayoutControl Orientation="Vertical" Width="*">
<dxlc:LayoutItem Label="Letzter Audit">
<TextBlock Text="{Binding LastAuditDate}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Nächster Audit">
<TextBlock Text="{Binding NextAuditDate}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Abweichungen">
<TextBlock Text="{Binding ComplianceViolationCount}" Foreground="Red" FontWeight="Bold" />
</dxlc:LayoutItem>
</dxlc:LayoutControl>
</dxlc:LayoutGroup>
<!-- Depreciation Report -->
<dxlc:LayoutGroup Caption="Abschreibungs-Bericht">
<dxg:GridControl ItemsSource="{Binding DepreciationReports}">
<dxg:GridColumn FieldName="AssetCategory" Header="Kategorie" Width="100" />
<dxg:GridColumn FieldName="TotalAssets" Header="Geräte" Width="70" />
<dxg:GridColumn FieldName="BookValue" Header="Buchwert" Width="100" />
<dxg:GridColumn FieldName="AccumulatedDepreciation" Header="Akkumulierte Abschreibung" Width="120" />
<dxg:GridColumn FieldName="DepreciationPercentage" Header="Abschreibung %" Width="100" />
</dxg:GridControl>
</dxlc:LayoutGroup>
<!-- Compliance Violations -->
<dxlc:LayoutGroup Caption="Compliance-Verstöße" MaxHeight="200">
<dxg:GridControl ItemsSource="{Binding ComplianceViolations}">
<dxg:GridColumn FieldName="ViolationType" Header="Typ" Width="120" />
<dxg:GridColumn FieldName="Description" Header="Beschreibung" Width="250" />
<dxg:GridColumn FieldName="AffectedAssets" Header="Betroffene Geräte" Width="100" />
<dxg:GridColumn FieldName="Severity" Header="Schweregrad" Width="80" />
<dxg:GridColumn FieldName="DueDate" Header="Fälligkeitsdatum" Width="100" />
</dxg:GridControl>
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</controls:BaseModule>
```
---
# SCHEDULING XAML VIEWS
## 17.1 AppointmentManagementView.xaml
**Pfad**: `src/centron/Centron.WPF.UI/Modules/Helpdesk/Scheduling/AppointmentManagementView.xaml`
**Pattern**: Calendar-based appointment scheduler
```xaml
<?xml version="1.0" encoding="utf-8"?>
<controls:BaseModule
xmlns:controls="clr-namespace:CentronSoftware.Centron.WPF.UI.Extension.Controls;assembly=Centron.WPF.UI.Extension"
xmlns:dxlc="http://schemas.devexpress.com/winfx/2008/xaml/layoutcontrol"
xmlns:dxg="http://schemas.devexpress.com/winfx/2008/xaml/grid"
xmlns:dxe="http://schemas.devexpress.com/winfx/2008/xaml/editors"
xmlns:dx="http://schemas.devexpress.com/winfx/2008/xaml/core"
xmlns:dxsch="http://schemas.devexpress.com/winfx/2008/xaml/scheduler"
xmlns:properties="clr-namespace:CentronSoftware.Centron.WPF.UI.Resources"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/expression/blend/2008"
x:Class="CentronSoftware.Centron.WPF.UI.Modules.Helpdesk.Scheduling.AppointmentManagementView">
<dxlc:LayoutControl Orientation="Vertical">
<!-- Filter -->
<dxlc:LayoutGroup Orientation="Horizontal" Caption="Filter" IsCollapsible="True">
<dxlc:LayoutItem Label="Techniker">
<dxe:ComboBoxEdit
ItemsSource="{Binding Technicians}"
DisplayMember="TechnicianName"
SelectedItem="{Binding SelectedTechnician}"
Width="200" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Kunde">
<dxe:ComboBoxEdit
ItemsSource="{Binding Customers}"
DisplayMember="CustomerName"
SelectedItem="{Binding SelectedCustomer}"
Width="200" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Von">
<dxe:DateEdit SelectedDate="{Binding StartDate}" Width="120" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Bis">
<dxe:DateEdit SelectedDate="{Binding EndDate}" Width="120" />
</dxlc:LayoutItem>
<dx:SimpleButton Content="Filtern" Command="{Binding FilterCommand}" Width="80" />
<dx:SimpleButton Content="Löschen" Command="{Binding ClearFiltersCommand}" Width="80" />
</dxlc:LayoutGroup>
<!-- Calendar View -->
<dxlc:LayoutControl Orientation="Horizontal">
<!-- Left: Appointment List -->
<dxlc:LayoutItem Width="350" AllowHorizontalSizing="True" Caption="Termine">
<dxg:GridControl
ItemsSource="{Binding Appointments}"
SelectedItem="{Binding SelectedAppointment}">
<dxg:GridColumn FieldName="AppointmentDate" Header="Datum" Width="80" />
<dxg:GridColumn FieldName="TimeSlot" Header="Zeit" Width="80" />
<dxg:GridColumn FieldName="CustomerName" Header="Kunde" Width="120" />
<dxg:GridColumn FieldName="TechnicianName" Header="Techniker" Width="100" />
<dxg:GridColumn FieldName="StatusName" Header="Status" Width="80" />
</dxg:GridControl>
</dxlc:LayoutItem>
<!-- Right: Appointment Details & Calendar -->
<dxlc:LayoutControl Orientation="Vertical" Width="*">
<!-- Calendar -->
<dxe:DateNavigator
SelectedDate="{Binding SelectedCalendarDate}"
Height="200" />
<!-- Day/Week/Month View -->
<dxsch:SchedulerControl
ItemsSource="{Binding Appointments}"
Height="400">
<dxsch:SchedulerControl.Views>
<dxsch:DayView />
<dxsch:WeekView />
<dxsch:MonthView />
</dxsch:SchedulerControl.Views>
</dxsch:SchedulerControl>
<!-- Details Form -->
<dxlc:LayoutGroup Caption="Termin-Details" Visibility="{Binding SelectedAppointment, Converter={StaticResource NullToVisibilityConverter}}">
<dxlc:LayoutItem Label="Kunde">
<dxe:ComboBoxEdit
ItemsSource="{Binding Customers}"
DisplayMember="CustomerName"
SelectedItem="{Binding SelectedAppointment.Customer}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Datum">
<dxe:DateEdit SelectedDate="{Binding SelectedAppointment.AppointmentDate}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Zeit">
<dxe:TimeEdit EditTime="{Binding SelectedAppointment.StartTime}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Dauer (Minuten)">
<dxe:SpinEdit Value="{Binding SelectedAppointment.DurationMinutes}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Techniker">
<dxe:ComboBoxEdit
ItemsSource="{Binding Technicians}"
DisplayMember="TechnicianName"
SelectedItem="{Binding SelectedAppointment.Technician}" />
</dxlc:LayoutItem>
<dxlc:LayoutItem Label="Beschreibung">
<dxe:MemoEdit Text="{Binding SelectedAppointment.Description}" Height="80" />
</dxlc:LayoutItem>
</dxlc:LayoutGroup>
<!-- Commands -->
<dxlc:LayoutGroup Orientation="Horizontal" Height="40">
<dx:SimpleButton Content="Neu" Command="{Binding CreateAppointmentCommand}" Width="100" />
<dx:SimpleButton Content="Speichern" Command="{Binding SaveAppointmentCommand}" Width="100" />
<dx:SimpleButton Content="Bestätigen" Command="{Binding ConfirmAppointmentCommand}" Width="100" />
<dx:SimpleButton Content="Absagen" Command="{Binding CancelAppointmentCommand}" Width="100" />
</dxlc:LayoutGroup>
</dxlc:LayoutControl>
</dxlc:LayoutControl>
</dxlc:LayoutControl>
</controls:BaseModule>
```
---
**Files Remaining**: 17.2, 17.3, 17.4 Scheduling Views follow similar patterns with:
- Route Optimization Map View
- Capacity Planning Grid with Heatmaps
- SLA Management Dashboard
---
## Summary
**Total XAML Templates Created**: 8 primary views
**DevExpress Components Used**:
- GridControl (Master-Detail lists)
- ComboBoxEdit (Dropdowns)
- DateEdit / TimeEdit (Date/Time selection)
- TextEdit / MemoEdit (Text input)
- ProgressBar (Status visualization)
- ChartControl (Metrics visualization)
- SchedulerControl (Calendar scheduling)
- LayoutControl (Layout management)
- SimpleButton (Commands)
**Binding Patterns**:
- ObservableCollection bindings
- Two-way bindings with UpdateSourceTrigger
- Value converters (BoolToVisibilityConverter, NullToVisibilityConverter)
- Conditional visibility based on selection state
**All templates follow**:
- UTF-8 with BOM encoding
- German localization via LocalizedStrings
- DevExpress 24.2.7 namespace conventions
- Master-Detail layout patterns
- Command binding patterns
- Responsive grid layouts