// Copyright (c) 2017 schick Informatik // Description: Kapselt den Locode - Lookup // using System; using System.Collections.Generic; using System.Windows; using System.Windows.Controls; using System.Windows.Media.Imaging; using ENI2.Locode; using bsmd.database; using System.ComponentModel; namespace ENI2.Controls { /// /// Interaction logic for LocodeControl.xaml /// public partial class LocodeControl : UserControl, INotifyPropertyChanged { private List _locodeList = new List(); public event PropertyChangedEventHandler PropertyChanged; private bool _comboSelect; public LocodeControl() { InitializeComponent(); } protected enum LocodeState { UNKNOWN, INVALID, OK, AMBIGUOUS }; /// /// used internally to load up drop down /// public List LocodeList { get { return this._locodeList; } set { this._locodeList = value; } } public string SelectedItem { get { return this.comboBoxLocode.SelectedItem as string; } set { this._locodeList.Clear(); string portName = null; switch (this.LocodeSource) { case RuleEngine.LocodeMode.NO_PORT_FLAG: portName = LocodeDB.LocationNameFromLocode(value); break; case RuleEngine.LocodeMode.STANDARD: portName = LocodeDB.PortNameFromLocode(value); break; case RuleEngine.LocodeMode.SSN: portName = LocodeDB.SSNPortNameFromLocode(value); break; } LocodeState locodeState = portName.IsNullOrEmpty() ? LocodeState.INVALID : LocodeState.OK; this.SetLocodeStateImage(this.imageLocodeState, locodeState); if (locodeState == LocodeState.OK) { string valString = string.Format("{0} - {1}", value, portName); this._locodeList.Add(valString); this.comboBoxLocode.ItemsSource = this.LocodeList; this.comboBoxLocode.SelectedItem = valString; } } } /// /// Actual value for DataBinding /// public string LocodeValue { get { return (string)GetValue(LocodeValueProperty); } set { SetValue(LocodeValueProperty, value); } } private static object LocodeValue_CoerceValue(DependencyObject dobj, object Value) { //called whenever dependency property value is reevaluated. The return value is the //latest value set to the dependency property // MessageBox.Show(string.Format("CoerceValue is fired : Value {0}", Value)); return Value; } public RuleEngine.LocodeMode LocodeSource { get; set; } #region static methods public static readonly DependencyProperty LocodeValueProperty = DependencyProperty.Register("LocodeValue", typeof(string), typeof(LocodeControl), new UIPropertyMetadata(null, LocodeValueChangedHandler, LocodeValue_CoerceValue)); public static void LocodeValueChangedHandler(DependencyObject sender, DependencyPropertyChangedEventArgs e) { // Get instance of current control from sender // and property value from e.NewValue if ((e.NewValue != null) && (e.NewValue.ToString().Trim() != "")) ((LocodeControl)sender).SelectedItem = e.NewValue.ToString();//.Substring(0,5); } #endregion #region event handler private void ComboBox_TextChanged(object sender, RoutedEventArgs e) { bool locodeFound = false; if (this._comboSelect) { this._comboSelect = false; this.SetLocodeStateImage(this.imageLocodeState, LocodeState.OK); } else { this.comboBoxLocode.ItemsSource = null; if (this.comboBoxLocode.Text.Length > 4) { this.LocodeList.Clear(); this.LocodeValue = null; // check if actual locode if (this.comboBoxLocode.Text.Length == 5) { string directLocode = this.comboBoxLocode.Text.Trim().ToUpper(); string portname = null; switch(this.LocodeSource) { case RuleEngine.LocodeMode.NO_PORT_FLAG: portname = LocodeDB.LocationNameFromLocode(directLocode); break; case RuleEngine.LocodeMode.STANDARD: portname = LocodeDB.PortNameFromLocode(directLocode); break; case RuleEngine.LocodeMode.SSN: portname = LocodeDB.SSNPortNameFromLocode(directLocode); break; } bool isLocode = !portname.IsNullOrEmpty(); if (isLocode) { this.comboBoxLocode.Text = string.Format("{0} - {1}", directLocode, portname); this.LocodeList.Add(string.Format("{0} - {1}", directLocode, portname)); this.SetLocodeStateImage(this.imageLocodeState, LocodeState.OK); this.LocodeValue = directLocode; locodeFound = true; } } if (!locodeFound) { // assume this is a harbour name typed out.. string lookupString = string.Format("%{0}%", this.comboBoxLocode.Text.Trim()); List locodeEntries = null; switch(this.LocodeSource) { case RuleEngine.LocodeMode.NO_PORT_FLAG: locodeEntries = LocodeDB.AllLocodesForCityNameAsEntries(lookupString, false); break; case RuleEngine.LocodeMode.STANDARD: locodeEntries = LocodeDB.AllLocodesForCityNameAsEntries(lookupString); break; case RuleEngine.LocodeMode.SSN: locodeEntries = LocalizedLookup.SSNAllLocodesForCityNameAsEntries(lookupString); break; } locodeEntries.Sort(); foreach (LocodeDB.LocodeEntry entry in locodeEntries) this.LocodeList.Add(string.Format("{0} - {1}", entry.Locode, entry.Name)); this.comboBoxLocode.ItemsSource = this.LocodeList; if (this.LocodeList.Count == 1) { this.comboBoxLocode.SelectedItem = this.LocodeList[0]; this.SetLocodeStateImage(this.imageLocodeState, LocodeState.OK); this.LocodeValue = this.LocodeList[0].Substring(0,5); } else if (this.LocodeList.Count == 0) { this.SetLocodeStateImage(this.imageLocodeState, LocodeState.INVALID); } else { this.SetLocodeStateImage(this.imageLocodeState, LocodeState.AMBIGUOUS); } } } } this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LocodeList")); } private void comboBoxLocode_SelectionChanged(object sender, SelectionChangedEventArgs e) { if (this.SelectedItem == null) this.LocodeValue = null; else { if (this.SelectedItem.Length > 5) { this.LocodeValue = this.SelectedItem.Substring(0, 5); this._comboSelect = true; } else { this.LocodeValue = this.SelectedItem; } } this.PropertyChanged?.Invoke(this, new PropertyChangedEventArgs("LocodeList")); } #endregion #region private/protected methods protected void SetLocodeStateImage(Image stateImage, LocodeState state) { switch (state) { case LocodeState.AMBIGUOUS: stateImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/bullet_ball_yellow.png")); break; case LocodeState.INVALID: stateImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/bullet_ball_red.png")); break; case LocodeState.OK: stateImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/bullet_ball_green.png")); break; case LocodeState.UNKNOWN: default: stateImage.Source = new BitmapImage(new Uri("pack://application:,,,/Resources/bullet_ball_grey.png")); break; } } #endregion private void comboBoxLocode_PreviewKeyDown(object sender, System.Windows.Input.KeyEventArgs e) { if((e.Key == System.Windows.Input.Key.Down) && !this.comboBoxLocode.IsDropDownOpen) { this.comboBoxLocode.IsDropDownOpen = true; e.Handled = true; } } } }