Files
Masterarbeit/Ergebnisse/Ergebnisse 03/USE_CASES_NEW_XAML_TEMPLATES.md

38 KiB

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

  2. Scheduling Views


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)
<?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

<?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

<?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

<?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

<?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

<?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