# c-entron.NET WPF GUI - Quick Reference & Developer Guide

## QUICK NAVIGATION

### To Find a Module:
- Path: `c:/src/centron/Centron.WPF.UI/Modules/{ModuleName}/`
- Main View: `{ModuleName}View.xaml` or `{ModuleName}ModuleView.xaml`
- ViewModel: `{ModuleName}ViewModel.cs` (same folder)
- Commands: In ViewModel constructor (`new DelegateCommand(...)`)
- Properties: In ViewModel as `{public PropertyName { get; set; }}`

### The 30 Modules:
1. Administration - Settings, users, config
2. ArtificialIntelligence - AI features
3. Calendar - Event scheduling
4. Dashboard - Home screen
5. DataExchange - Import/export
6. ExternalTool - Third-party integrations
7. Finances - Accounting, billing, CRM
8. Global - Shared components
9. Gui - UI utilities
10. Helpdesk - Tickets, support
11. Logistic - Shipping, tracking
12. Massenupdates - Bulk operations
13. MyCentron - Personal workspace
14. OnlineBanking - Bank connections
15. PasswordManager - Credentials
16. PayersAndCostCenter - Cost allocation
17. PLM - Product lifecycle
18. Production - Manufacturing
19. ProjectManagement - Projects, tasks
20. ProjectPriceImport - Pricing import
21. Purchasing - PO, suppliers, EDI
22. QM - Quality management
23. Reports - Reporting engine
24. Rma - Return management
25. Sales - Orders, quotations
26. Statistics - Analytics
27. Survey - Feedback forms
28. TelekomDive - Telecom integration
29. Warehousing - Inventory, articles
30. (Additional system modules)

---

## MOST IMPORTANT VIEWMODELS TO KNOW

### 1. TicketListViewModel [CRITICAL - 8+ CONTEXTS]
**File**: `Helpdesk/TicketList/TicketListViewModel.cs`
**Used in**: Helpdesk, Finances (account tickets), Sales, Warehousing, Reports, Dashboard, MyCentron
**Key Insight**: Context-aware filtering - same ViewModel, different data contexts
**When to Use**: Any list of tickets needed, embed directly, use filters to customize

### 2. AccountManagementViewModel [HIGH REUSE - 8+ CONTEXTS]
**File**: `Finances/AccountManagement/AccountManagementViewModel.cs`
**Contains**: 5 nested ViewModels (Receipts, Tickets, Statistics, etc.)
**When to Use**: Customer/account detail views

### 3. ReceiptsOverviewViewModel
**File**: `Finances/AccountManagement/ReceiptControls/ReceiptsOverviewViewModel.cs`
**Used in**: Finances, Accounting, CRM, Reports
**Feature**: Multi-receipt type support (Invoice, Credit note, Delivery list)

### 4. Dashboard ViewModels (7 variations)
**Pattern**: Each shows single metric (Status, Priority, Type, Date, etc.)
**Reuse**: All 7 embedded in multiple dashboard views

### 5. CountryManagementViewModel
**File**: `Administration/CountryManagement/CountryManagementViewModel.cs`
**Pattern**: Master-detail with 10 commands
**Ideal Example**: Study this for standard MVVM patterns

---

## TYPICAL MODULE STRUCTURE

```
ModuleName/
├── ModuleNameView.xaml (main view)
├── ModuleNameViewModel.cs (main ViewModel)
├── ViewModels/
│   ├── DetailViewModel.cs
│   ├── SubModuleViewModel.cs
│   └── FilterViewModel.cs
├── Views/
│   ├── DetailView.xaml
│   └── SubModuleView.xaml
├── Converters/
│   ├── CustomConverter.cs
│   └── FilterConverter.cs
├── Dialogs/
│   ├── SearchDialogView.xaml
│   └── SearchDialogViewModel.cs
└── [SubModule]/
    ├── SubModuleView.xaml
    └── SubModuleViewModel.cs
```

---

## ADDING A NEW FEATURE

### Step 1: Identify the ViewModel
- Is it EXISTING reusable? Use existing (e.g., TicketListViewModel)
- Is it NEW to this module? Create new class: `{Feature}ViewModel.cs`

### Step 2: Add Command (If action is needed)
```csharp
public DelegateCommand SaveCommand { get; }

public FeatureViewModel()
{
    this.SaveCommand = new DelegateCommand(this.Save, () => !this.IsLoading);
}

private void Save()
{
    // Your business logic
}
```

### Step 3: Add Property (If data display/binding needed)
```csharp
private string _featureName;
public string FeatureName
{
    get => this._featureName;
    set => this.SetProperty(ref this._featureName, value, nameof(this.FeatureName));
}
```

### Step 4: Add to XAML View
```xaml
<!-- For property binding -->
<TextEdit EditValue="{Binding FeatureName, UpdateSourceTrigger=PropertyChanged}" />

<!-- For command binding -->
<Button Command="{Binding SaveCommand}" Content="Speichern" />

<!-- For data binding -->
<GridControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
```

### Step 5: Test in multiple contexts
- Standalone view
- Embedded in dialog
- Nested in another ViewModel
- Multi-select scenarios

---

## REUSING EXISTING VIEWMODEL

### Use Case: Add ticket list to new module

**Step 1**: Reference TicketListViewModel
```xaml
<!-- In parent View.xaml -->
<TabItem Header="Tickets">
    <ticketList:TicketListView DataContext="{Binding TicketListViewModel}" />
</TabItem>
```

**Step 2**: Create nested property in parent ViewModel
```csharp
private TicketListViewModel _ticketListViewModel;
public TicketListViewModel TicketListViewModel
{
    get { return this._ticketListViewModel; }
    set { this.SetProperty(ref this._ticketListViewModel, value, () => this.TicketListViewModel); }
}

// In constructor:
public ParentViewModel()
{
    this.TicketListViewModel = new TicketListViewModel();
    // Optional: Set context/filter
    this.TicketListViewModel.PreFilterByCustomer(this.SelectedCustomer.Id);
}
```

**Step 3**: That's it! The TicketListViewModel handles its own filtering and commands

---

## COMMON PATTERNS

### Master-Detail List
```xaml
<LayoutControl Orientation="Horizontal">
  <!-- Master (left) -->
  <LayoutItem Width="250" AllowHorizontalSizing="True">
    <GridControl ItemsSource="{Binding Items}" SelectedItem="{Binding SelectedItem}" />
  </LayoutItem>
  
  <!-- Detail (right) -->
  <LayoutGroup Width="*">
    <TextEdit EditValue="{Binding SelectedItem.Name}" />
    <!-- More detail controls -->
  </LayoutGroup>
</LayoutControl>
```

### Collapsible Filter Section
```xaml
<LayoutGroup IsCollapsible="True" Visibility="{Binding ShowFilter, Converter={StaticResource BooleanToVisibilityConverter}}">
  <LayoutGroup.HeaderTemplate>
    <DataTemplate>
      <StackPanel Orientation="Horizontal">
        <TextBlock Text="Filter" />
        <Button Command="{Binding ClearFiltersCommand}" Content="Löschen" />
      </StackPanel>
    </DataTemplate>
  </LayoutGroup.HeaderTemplate>
  
  <!-- Filter controls -->
  <TextEdit EditValue="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />
  <DateEdit SelectedDate="{Binding StartDate}" />
  <!-- More filters -->
</LayoutGroup>
```

### Ribbon Toolbar
```xaml
<RibbonControl>
  <RibbonDefaultPageCategory>
    <RibbonPage>
      <RibbonPageGroup Caption="Daten">
        <BarButtonItem Command="{Binding SaveCommand}" Content="Speichern" Glyph="16x16/Save.png" />
      </RibbonPageGroup>
      <RibbonPageGroup Caption="Entity">
        <BarButtonItem Command="{Binding NewCommand}" Content="Neu" RibbonStyle="Large" />
      </RibbonPageGroup>
    </RibbonPage>
  </RibbonDefaultPageCategory>
</RibbonControl>
```

### Wizard Pattern
```xaml
<TabControl SelectedIndex="{Binding CurrentPageIndex}">
  <TabItem Header="Step 1"><local:Step1View /></TabItem>
  <TabItem Header="Step 2"><local:Step2View /></TabItem>
  <TabItem Header="Step 3"><local:Step3View /></TabItem>
</TabControl>

<StackPanel Orientation="Horizontal">
  <Button Command="{Binding PreviousCommand}" />
  <Button Command="{Binding NextCommand}" />
  <Button Command="{Binding FinishCommand}" />
</StackPanel>
```

### Tab Control with Nested ViewModels
```xaml
<TabControl>
  <TabItem Header="Receipts">
    <local:ReceiptsView DataContext="{Binding ReceiptsViewModel}" />
  </TabItem>
  <TabItem Header="Tickets">
    <local:TicketListView DataContext="{Binding TicketListViewModel}" />
  </TabItem>
  <TabItem Header="Statistics">
    <local:StatisticsView DataContext="{Binding StatisticsViewModel}" />
  </TabItem>
</TabControl>
```

---

## DEVEXPRESS CONTROL REFERENCE

### Essential Controls

| Control | Namespace | Usage | XAML Example |
|---------|-----------|-------|--------------|
| GridControl | dxg | Data display/edit | `<dxg:GridControl ItemsSource="{Binding Items}" />` |
| TextEdit | dxe | Single-line text | `<dxe:TextEdit EditValue="{Binding Text}" />` |
| ComboBox | dxe | Dropdown list | `<dxe:ComboBox ItemsSource="{Binding Items}" SelectedItem="{Binding Selected}" />` |
| DateEdit | dxe | Date picker | `<dxe:DateEdit SelectedDate="{Binding Date}" />` |
| SpinEdit | dxe | Numeric input | `<dxe:SpinEdit Value="{Binding Count}" />` |
| CheckEdit | dxe | Checkbox | `<dxe:CheckEdit IsChecked="{Binding IsActive}" />` |
| ButtonEdit | dxe | Text with button | `<dxe:ButtonEdit EditValue="{Binding Value}"><dxe:ButtonInfo GlyphKind="Search" /></dxe:ButtonEdit>` |
| RichTextEdit | dxe | Rich text | `<dxe:RichTextEdit Text="{Binding Content}" />` |
| RibbonControl | dxr | Toolbar | `<dxr:RibbonControl><dxr:RibbonPage>...</dxr:RibbonPage></dxr:RibbonControl>` |
| LayoutControl | dxcl | Responsive layout | `<dxcl:LayoutControl><dxcl:LayoutItem>...</dxcl:LayoutItem></dxcl:LayoutControl>` |
| ChartControl | dxc | Charts/graphs | `<dxc:ChartControl DataSource="{Binding Data}" />` |

### Binding Modes
```xaml
<!-- Real-time updates -->
<TextEdit EditValue="{Binding SearchText, UpdateSourceTrigger=PropertyChanged}" />

<!-- Standard binding (update on focus loss) -->
<TextEdit EditValue="{Binding Name}" />

<!-- One-way binding (display only) -->
<TextBlock Text="{Binding Status, Mode=OneWay}" />

<!-- With converter -->
<TextBlock Text="{Binding Date, Converter={StaticResource DateConverter}}" />
```

---

## DEBUGGING TIPS

### 1. ViewModel not updating UI?
- Check: `SetProperty()` called correctly? ✓
- Check: Property name correct in binding? ✓
- Check: `UpdateSourceTrigger=PropertyChanged` if real-time needed? ✓

### 2. Command not firing?
- Check: Command instantiated in constructor? ✓
- Check: `CanExecute` condition met? (Default true) ✓
- Check: ViewModel set as DataContext? ✓

### 3. GridControl empty?
- Check: `ItemsSource` bound correctly? ✓
- Check: Collection has data (not null or empty)? ✓
- Check: Columns defined in GridControl? ✓

### 4. Filter not working?
- Check: `UpdateSourceTrigger=PropertyChanged` on filter control? ✓
- Check: Filter method called on property change? ✓
- Check: `RefreshList()` or `ReloadData()` method exists? ✓

### 5. Nested ViewModel not showing?
- Check: Child ViewModel instantiated? ✓
- Check: Child View's DataContext bound to ViewModel property? ✓
- Check: Visibility/IsEnabled conditions? ✓

---

## PERFORMANCE OPTIMIZATION

### 1. Use Virtual Scrolling for Large Lists
```xaml
<dxg:GridControl VirtualScrollingMode="Vertical" />
```

### 2. Defer Loading for Tab Content
```csharp
public void OnTabSelected()
{
    if (this.NestedViewModel == null)
    {
        this.NestedViewModel = new NestedViewModel();
        this.NestedViewModel.LoadData();
    }
}
```

### 3. Use Async Loading with Progress
```csharp
private async Task LoadData()
{
    this.IsLoading = true;
    try
    {
        this.Items = await this.LoadItemsAsync();
    }
    finally
    {
        this.IsLoading = false;
    }
}
```

### 4. Implement IDisposable for Resource Cleanup
```csharp
public class MyViewModel : ViewModelBase, IDisposable
{
    public void Dispose()
    {
        // Clean up subscriptions, timers, etc.
    }
}
```

---

## LOCALIZATION (German/English)

### All UI Strings via LocalizedStrings
```csharp
// In code:
MessageBox.Show(LocalizedStrings.ConfirmDeleteMessage);

// In XAML:
<Button Content="{x:Static properties:LocalizedStrings.SaveButtonLabel}" />
```

### Key Format Convention
```
{ClassName}_{Method}_{Description}
Example: CountryManagementView_NewCountry_ButtonLabel
```

---

## BEST PRACTICES CHECKLIST

- [ ] Commands use CanExecute to prevent invalid states
- [ ] Properties use SetProperty() for change notification
- [ ] Collections are ObservableCollection<T>
- [ ] Async operations don't freeze UI (use AsyncCommand)
- [ ] All UI text from LocalizedStrings resource
- [ ] Master-detail pattern for complex data entry
- [ ] Filters are collapsible to save space
- [ ] Ribbon used for primary actions
- [ ] No business logic in View code-behind
- [ ] ViewModels are testable (no UI dependencies)

---

## FILE ORGANIZATION

### View Files
- Location: `Modules/{ModuleName}/{Feature}/`
- Naming: `{FeatureName}View.xaml`
- Content: Only XAML markup (x:Class points to code-behind)

### ViewModel Files
- Location: `Modules/{ModuleName}/{Feature}/` or `ViewModels/` subfolder
- Naming: `{FeatureName}ViewModel.cs`
- Content: Properties, Commands, Data access logic

### Converter Files
- Location: `Modules/{ModuleName}/{Feature}/Converters/` or `Modules/{ModuleName}/Converters/`
- Naming: `{ConverterName}Converter.cs`
- Content: IValueConverter implementation

### Dialog Files
- Location: `Modules/{ModuleName}/{Feature}/Dialogs/`
- Naming: `{DialogName}DialogView.xaml` + `{DialogName}DialogViewModel.cs`
- Content: Modal dialog UI and logic

---

## SUMMARY OF KEY INSIGHTS

1. **Extreme Reuse Pattern**: TicketListViewModel appears in 8+ different contexts - STUDY THIS PATTERN
2. **Context-Aware Filtering**: Same ViewModel behaves differently based on which module uses it
3. **Nested ViewModels**: Complex screens use 5+ nested ViewModels for separation of concerns
4. **Master-Detail Ubiquity**: 80% of data entry uses left-panel list + right-panel detail
5. **Command-Based Architecture**: All actions via ICommand (no code-behind logic)
6. **Async-First**: All long-running operations prevent UI freezing with async/await
7. **Soft Deletes Only**: No permanent deletion (IsDeleted flag), audit trails maintained
8. **Permission Integration**: UI elements conditionally visible based on user rights
9. **DevExpress Heavy**: 95% of controls from DevExpress framework (not WPF standard)
10. **German-First Localization**: Default to German, English translation maintained in parallel

