git_bsmd/ENI2/DetailBaseControl.cs

367 lines
14 KiB
C#

// Copyright (c) 2017 schick Informatik
// Description: Basisklasse für die Detailansichten. Hier sollten Dinge wie Validierung etc. abgehandelt werden
//
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Text.RegularExpressions;
using System.Windows.Controls;
using Xceed.Wpf.Toolkit;
using bsmd.database;
using ENI2.Util;
using ENI2.Controls;
namespace ENI2
{
public class DetailBaseControl : UserControl, IHighlightControlContainer
{
#region Fields
protected bool _initialized = false;
private DependencyPropertyDescriptor _dpTextBox;
private DependencyPropertyDescriptor _dpDateTimePicker;
private DependencyPropertyDescriptor _dpDatePicker;
private DependencyPropertyDescriptor _dpLocode;
private DependencyPropertyDescriptor _dpCheckbox;
private DependencyPropertyDescriptor _dpComboboxIndex;
private DependencyPropertyDescriptor _dpComboboxValue;
private DependencyPropertyDescriptor _dpNumericUpdown;
private DependencyPropertyDescriptor _dpIntUpdown;
private readonly Dictionary<Object, Message.NotificationClass> _controlClassDict = new Dictionary<object, Message.NotificationClass>();
private readonly Dictionary<Message.NotificationClass, Message> _typeMessageDict = new Dictionary<Message.NotificationClass, Message>();
private static readonly Regex rdt = new Regex(@"^(\d{12})$");
private static readonly Regex rd = new Regex(@"^(\d{8})$");
#endregion
#region enum
protected enum LocodeState
{
UNKNOWN,
INVALID,
OK,
AMBIGUOUS
}
#endregion
#region events
/// <summary>
/// Mit diesem event kann ein Listenelement den programmatischen Sprung auf ein anderes Listenelement auslösen
/// (das wird zunächst nur vom Overview -> Auswahl Meldeklasse verwendet)
/// </summary>
public event Action<int> JumpToListElementRequest;
/// <summary>
/// Mit diesem Event kann ein Listen-Element einen Reload der gesamten Anmeldung auslösen
/// </summary>
public event Action<Guid> RequestReload;
/// <summary>
/// Damit kann ein Listenelement eine Validierung der gesamten Anmeldung auslösen (inkl. Highlighting) (auf Knopfdruck)
/// </summary>
public event Action RequestValidate;
/// <summary>
/// Alle Meldeklassen die auf "zu versenden" stehen werden validiert und falls die Validierung scheitert auf "SUSPEND" gestellt
/// </summary>
public event Action RequestSendValidation;
/// <summary>
/// Damit kann signalisiert werden, dass die Anmeldung readonly wird (z.B. bei Storno)
/// </summary>
public event Action RequestDisable;
/// <summary>
/// Damit kann aus einer Anmeldung heraus die Kopier-Logik ausgelöst werden
/// </summary>
public event Action RequestCopy;
/// <summary>
/// Eine in der Detailansicht enthaltene Meldeklasse hat sich geändert
/// </summary>
public event Action<Message.NotificationClass?> NotificationClassChanged;
/// <summary>
/// Eine Maske soll neu erzeugt werden weil sich dort "indirekt" etwas geändert hat durch eine Änderung in einer anderen Maske.
/// (Beispiel Copy HAZA nach HAZD Elemente)
/// </summary>
public event Action<string> ResetControlCache;
#endregion
#region Properties
/// <summary>
/// Core to be edited
/// </summary>
public MessageCore Core { get; set; }
/// <summary>
/// all messages for this core
/// </summary>
public List<Message> Messages { get; set; }
/// <summary>
/// particular messages that are edited on this page
/// </summary>
public List<Message> ControlMessages { get; } = new List<Message>();
public bool LockedByOtherUser { get; set; }
#endregion
#region public methods
public virtual void Initialize() {
_dpTextBox = DependencyPropertyDescriptor.FromProperty(TextBox.TextProperty, typeof(TextBox));
_dpDateTimePicker = DependencyPropertyDescriptor.FromProperty(Xceed.Wpf.Toolkit.DateTimePicker.ValueProperty, typeof(Xceed.Wpf.Toolkit.DateTimePicker));
_dpDatePicker = DependencyPropertyDescriptor.FromProperty(DatePicker.SelectedDateProperty, typeof(DatePicker));
_dpLocode = DependencyPropertyDescriptor.FromProperty(Controls.LocodeControl.LocodeValueProperty, typeof(Controls.LocodeControl));
_dpCheckbox = DependencyPropertyDescriptor.FromProperty(CheckBox.IsCheckedProperty, typeof(CheckBox));
_dpComboboxIndex = DependencyPropertyDescriptor.FromProperty(ComboBox.SelectedIndexProperty, typeof(ComboBox));
_dpComboboxValue = DependencyPropertyDescriptor.FromProperty(ComboBox.SelectedValueProperty, typeof(ComboBox));
_dpNumericUpdown = DependencyPropertyDescriptor.FromProperty(Xceed.Wpf.Toolkit.DoubleUpDown.ValueProperty, typeof(Xceed.Wpf.Toolkit.DoubleUpDown));
_dpIntUpdown = DependencyPropertyDescriptor.FromProperty(Xceed.Wpf.Toolkit.IntegerUpDown.ValueProperty, typeof(Xceed.Wpf.Toolkit.IntegerUpDown));
foreach(Message message in this.Messages)
{
_typeMessageDict[message.MessageNotificationClass] = message;
}
}
public virtual void SetEnabled(bool enabled)
{
this.IsEnabled = enabled;
}
#endregion
#region protected methods
protected virtual void OnJumpToListElementRequest(int index)
{
this.JumpToListElementRequest?.Invoke(index);
}
protected virtual void OnRequestReload(Guid coreId)
{
this.RequestReload?.Invoke(coreId);
}
protected virtual void OnRequestValidate()
{
this.RequestValidate?.Invoke();
}
protected virtual void OnRequestSendValidation()
{
this.RequestSendValidation?.Invoke();
}
protected virtual void OnRequestDisable()
{
this.RequestDisable?.Invoke();
}
protected virtual void OnRequestCopy()
{
this.RequestCopy?.Invoke();
}
protected virtual void OnControlCacheReset(string messageGroupName)
{
this.ResetControlCache?.Invoke(messageGroupName);
}
#region event handling for control content changes (signal dirty etc)
protected void RegisterTextboxChange(TextBox textBox, Message.NotificationClass notificationClass)
{
this._dpTextBox.AddValueChanged(textBox, this.controlContentChanged);
this._controlClassDict[textBox] = notificationClass;
}
protected void UnregisterTextboxChange(TextBox textBox)
{
this._dpTextBox.RemoveValueChanged(textBox, this.controlContentChanged);
if (this._controlClassDict.ContainsKey(textBox))
this._controlClassDict.Remove(textBox);
}
protected void RegisterDateTimePickerChange(Xceed.Wpf.Toolkit.DateTimePicker dateTimePicker, Message.NotificationClass notificationClass)
{
this._dpDateTimePicker.AddValueChanged(dateTimePicker, this.controlContentChanged);
this._controlClassDict[dateTimePicker] = notificationClass;
}
protected void RegisterDatePickerChange(DatePicker datePicker, Message.NotificationClass notificationClass)
{
this._dpDatePicker.AddValueChanged(datePicker, this.controlContentChanged);
this._controlClassDict[datePicker] = notificationClass;
}
protected void RegisterLocodeChange(Controls.LocodeControl locodeControl, Message.NotificationClass notificationClass)
{
this._dpLocode.AddValueChanged(locodeControl, this.controlContentChanged);
this._controlClassDict[locodeControl] = notificationClass;
}
protected void RegisterCheckboxChange(CheckBox checkBox, Message.NotificationClass notificationClass)
{
this._dpCheckbox.AddValueChanged(checkBox, this.controlContentChanged);
this._controlClassDict[checkBox] = notificationClass;
}
protected void RegisterComboboxIndexChange(ComboBox comboBox, Message.NotificationClass notificationClass)
{
this._dpComboboxIndex.AddValueChanged(comboBox, this.controlContentChanged);
this._controlClassDict[comboBox] = notificationClass;
}
protected void RegisterComboboxValueChange(ComboBox comboBox, Message.NotificationClass notificationClass)
{
this._dpComboboxValue.AddValueChanged(comboBox, this.controlContentChanged);
this._controlClassDict[comboBox] = notificationClass;
}
protected void RegisterDoubleUpDownChange(Xceed.Wpf.Toolkit.DoubleUpDown doubleUpDown, Message.NotificationClass notificationClass)
{
this._dpNumericUpdown.AddValueChanged(doubleUpDown, this.controlContentChanged);
this._controlClassDict[doubleUpDown] = notificationClass;
}
protected void RegisterIntegerUpDownChange(Xceed.Wpf.Toolkit.IntegerUpDown intUpDown, Message.NotificationClass notificationClass)
{
this._dpIntUpdown.AddValueChanged(intUpDown, this.controlContentChanged);
this._controlClassDict[intUpDown] = notificationClass;
}
protected void SublistElementChanged(Message.NotificationClass notificationClass)
{
if (_typeMessageDict.ContainsKey(notificationClass))
{
if (!_typeMessageDict[notificationClass].IsDirty)
{
if (!_typeMessageDict[notificationClass].IsDirty)
{
_typeMessageDict[notificationClass].IsDirty = true;
// signal this notification class changed..
this.OnNotificationClassChanged(notificationClass);
}
}
}
}
protected void OnNotificationClassChanged(Message.NotificationClass? notificationClass)
{
this.NotificationClassChanged?.Invoke(notificationClass);
}
#region "BHV Spezial" Datetime Parsing..
protected void DateTimePicker_PreviewKeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
if ((sender is DateTimePicker thePicker) && rdt.IsMatch(thePicker.Text))
{
try
{
string timevalText = rdt.Match(thePicker.Text).Captures[0].Value;
int day = Int32.Parse(timevalText.Substring(0, 2));
int month = Int32.Parse(timevalText.Substring(2, 2));
int year = Int32.Parse(timevalText.Substring(4, 4));
int hour = Int32.Parse(timevalText.Substring(8, 2));
int minute = Int32.Parse(timevalText.Substring(10, 2));
thePicker.Value = new DateTime(year, month, day, hour, minute, 0);
}
catch (Exception) {
thePicker.Value = null;
}
}
}
protected void DateTimePicker_PreviewKeyUpDate(object sender, System.Windows.Input.KeyEventArgs e)
{
if ((sender is DatePicker thePicker) && rd.IsMatch(thePicker.Text))
{
try
{
string timevalText = rd.Match(thePicker.Text).Captures[0].Value;
int day = Int32.Parse(timevalText.Substring(0, 2));
int month = Int32.Parse(timevalText.Substring(2, 2));
int year = Int32.Parse(timevalText.Substring(4, 4));
thePicker.SelectedDate = new DateTime(year, month, day, 0, 0, 0);
}
catch (Exception) {
thePicker.SelectedDate = null;
}
}
}
#endregion
#endregion
#region private
private void controlContentChanged(object ctrl, EventArgs args)
{
if (this._controlClassDict.ContainsKey(ctrl))
{
Message.NotificationClass notificationClass = this._controlClassDict[ctrl];
this.SublistElementChanged(notificationClass);
}
else
{
System.Diagnostics.Trace.WriteLine("no notification class registered for control!!");
}
}
#endregion
#region combobox content filtering
protected void ComboBox_KeyUp(object sender, System.Windows.Input.KeyEventArgs e)
{
ComboBox cmb = sender as ComboBox;
GlobalStructures.FilterCombobox(cmb, e.Key);
}
#endregion
#endregion
#region IHighlightControlContainer implementation
public virtual void HighlightErrorMessageContainer()
{
//throw new NotImplementedException();
}
public virtual void HighlightViolationMessageContainer()
{
//throw new NotImplementedException();
}
public virtual void HighlightProperty(Message theMessage, string propertyName, string identifier, HighlightService.HighlightStyle style)
{
throw new NotImplementedException();
}
#endregion
}
}