protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content") { if (prop == null) { wxText.Text = ""; } else if (prop.Content != null) { if (Translate) { wxText.Text = LimeLanguage.Translate(LanguageSection, prop.Value, prop.Value); } else { wxText.Text = prop.Value; } } else { wxText.Text = prop.Name; } } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content") { // Convert the property to IList if (prop == null) { Cache = new List <object>(); } else if (prop.Content is IList list) { Cache = list; } else if (prop.Content is IEnumerable enu && !(prop.Content is string)) { Cache = new List <object>(); foreach (var item in enu) { Cache.Add(item); } } else if (prop.Content != null) { Cache = new List <object> { prop.Content }; } else { Cache = new List <object>(); } Index = 0; }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName)) { wxValidation.Source = prop; } if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Multiline") { if (prop != null && prop.Multiline) { wxMain.TextWrapping = TextWrapping.Wrap; wxMain.MaxLines = 5; if (prop.Type == typeof(string)) { wxMain.SetBinding(SpellCheck.IsEnabledProperty, new Binding("SpellCheck") { Source = Global.User }); } else { SpellCheck.SetIsEnabled(wxMain, false); } ToolTip = null; } else { wxMain.TextWrapping = TextWrapping.NoWrap; SpellCheck.SetIsEnabled(wxMain, false); if (HeaderEnabled) { wxMain.SetBinding(ToolTipProperty, new Binding("Text") { RelativeSource = new RelativeSource(RelativeSourceMode.Self) }); } else { ToolTip = null; } } } if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "ReadOnly") { wxMain.IsReadOnly = ReadOnly || (prop != null && prop.ReadOnly); } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content") { // Support different kinds of colors if (prop == null) { // Do Nothing } else if (prop.Type == typeof(System.Drawing.Color)) { var val = (System.Drawing.Color)prop.Content; Cache = Color.FromArgb(val.A, val.R, val.G, val.B); } else if (prop.Type == typeof(Color)) { Cache = (Color)prop.Content; } } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content") { LimeMsg.Debug("LimeListView OnPropertyChanged: {0} : {1} : {2}", prop, prop?.Ident, e?.PropertyName); int idx = 0; // Bellow we try to re-use the existing controls to avoid rendering overhead if (prop != null) { LimePropertyCollection collec; if (typeof(LimePropertyCollection).IsAssignableFrom(prop.Type)) { collec = (LimePropertyCollection)prop.Content; } else { collec = new LimePropertyCollection(null, prop); } for (int i = 0; i < collec.Count; i++) { var sprop = collec[i]; LimeControl wxctrl = null; var type = LimeControlSelector(sprop); if (type == null) { continue; } if (idx < wxMain.Items.Count) { var wxitem = (LimeControl)wxMain.Items[idx]; var propitem = (LimeProperty)wxitem.DataContext; if (type == wxitem.GetType()) { LimeMsg.Debug("LimeListView OnPropertyChanged: recycle {0} : {1} --> {2}", idx, propitem, sprop); wxitem.DataContext = sprop; wxitem.Visibility = sprop?.Visible == true ? Visibility.Visible : Visibility.Collapsed; } else { LimeMsg.Debug("LimeListView OnPropertyChanged: replaced {0} : {1} --> {2}", idx, propitem, sprop); wxMain.Items[idx] = wxctrl = (LimeControl)Activator.CreateInstance(type); } } else { LimeMsg.Debug("LimeListView OnPropertyChanged: new {0} : {1}", idx, sprop); wxMain.Items.Add(wxctrl = (LimeControl)Activator.CreateInstance(type)); } if (wxctrl != null) { wxctrl.IsTabStop = false; wxctrl.Level = Level > 0.11 ? Level - 0.1 : Level; wxctrl.ReadOnly = ReadOnly; wxctrl.HeaderEnabled = HeaderEnabled; wxctrl.ValidateOnChange = ValidateOnChange; wxctrl.DataContext = sprop; } idx++; } } // Hide remaining items from previous bindings for (; idx < wxMain.Items.Count; idx++) { var wxitem = (LimeControl)wxMain.Items[idx]; wxitem.DataContext = null; wxitem.Visibility = Visibility.Collapsed; } } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Type") { // Create the Menu (ListBox): Use different schemes depending on the type wxMenu.Items.Clear(); wxMenu.ItemTemplate = null; wxMenu.ItemsSource = null; var attrs = prop?.PInfo?.GetCustomAttributes(typeof(PickCollectionAttr), true); if (prop == null) { // Not supported wxMenu.ItemsSource = null; } else if (attrs != null && attrs.Length > 0) { // PickCollectionAttr var attr = (PickCollectionAttr)attrs[0]; wxMenu.DisplayMemberPath = attr.Name ?? attr.Key ?? attr.Value; wxMenu.SelectedValuePath = attr.Key; wxMenu.SetBinding(ListBox.ItemsSourceProperty, new Binding(attr.Items) { Source = prop.Source }); } else if (prop.Type.IsEnum) { bool checkbox = prop.Type.IsDefined(typeof(FlagsAttribute), inherit: false); if (checkbox) { // Enum Flags SetItemSourceEnumFlags(prop.Type); } else { // Enum var items = new List <ItemViewModel>(); foreach (var key in Enum.GetNames(prop.Type)) { items.Add(new ItemViewModel(key, prop.Type)); } wxMenu.ItemTemplate = (DataTemplate)Resources["EnumItemTemplate"]; wxMenu.ItemsSource = items; } } else if (typeof(IPickCollection).IsAssignableFrom(prop.Type)) { // do nothing for now var items = new List <ItemViewModel>(); if (prop.Content is IPickCollection collec) { foreach (var key in collec.Keys) { items.Add(new ItemViewModel(key)); } if (collec.Names != null) { int idx = 0; foreach (var val in collec.Names) { items[idx++].Name = val; } } } wxMenu.ItemTemplate = (DataTemplate)Resources["PickCollectionItemTemplate"]; wxMenu.ItemsSource = items; } else if (prop.Type == typeof(FontFamily)) { // FontFamily var familySrc = Fonts.SystemFontFamilies; var items = new List <ItemViewModel>(); items.Add(new ItemViewModel("", "<default>")); foreach (var val in familySrc) { items.Add(new ItemViewModel(val.ToString())); } wxText.SetBinding(TextBlock.FontFamilyProperty, new Binding("Value") { Converter = (IValueConverter)Resources["FontFamilyConvert"] } ); wxMenu.ItemTemplate = (DataTemplate)Resources["FontFamilyItemTemplate"]; wxMenu.ItemsSource = items; } else if (prop.Type == typeof(FontWeight) || prop.Type == typeof(FontStyle)) { var type = prop.Type == typeof(FontWeight) ? typeof(FontWeights) : typeof(FontStyles); var elms = type.GetProperties(); var items = new List <ItemViewModel>(); foreach (var pi in elms) { items.Add(new ItemViewModel(pi.Name, prop.Type)); } wxMenu.ItemTemplate = (DataTemplate)Resources[prop.Type.Name + "ItemTemplate"]; wxMenu.ItemsSource = items; } else { // Not supported wxMenu.ItemsSource = null; } } if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content") { if (prop == null) { // Do nothing } else if (Cache == null || !Cache.Equals(prop.Content)) { bool checkbox = prop.Type.IsDefined(typeof(FlagsAttribute), inherit: false); Cache = prop.Value; ValidateValue(set: false); } } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Icon" || e.PropertyName == "Content") { wxToolBar.Items.Clear(); // Add ToolBar Icon (if any) if (!string.IsNullOrEmpty(prop.Icon)) { wxToolBar.Items.Add(new LimeIcon() { IconKey = prop.Icon }); } // Get the list of LimeProperties var list = prop.Content as IEnumerable; if (list == null) { return; } foreach (var elm in list) { if (elm is LimeProperty sprop && sprop.Visible) { // Create the Content of the wxMain Border: // <ButtonBase ToolTip="{Binding Desc}" PreviewKeyDown="FixFocus_PreviewKeyDown"> // <StackPanel x:Name="wxPanel" Orientation="Horizontal"> // </StackPanel> // </ButtonBase> ButtonBase wxButton; if (sprop.Type == typeof(bool) || sprop.Type == typeof(bool?)) { wxButton = new ToggleButton(); wxButton.SetBinding(ToggleButton.IsCheckedProperty, new Binding("Content")); } else { wxButton = new Button(); wxButton.SetBinding(ButtonBase.CommandProperty, new Binding("Content")); } wxButton.DataContext = sprop; wxButton.SetBinding(ToolTipProperty, new Binding("Desc")); wxButton.PreviewKeyDown += FixFocus_PreviewKeyDown; var wxPanel = new StackPanel() { Orientation = Orientation.Horizontal }; wxButton.Content = wxPanel; if (!string.IsNullOrEmpty(sprop.Icon)) { wxPanel.Children.Add(new LimeIcon() { IconKey = sprop.Icon }); } //wxPanel.Children.Add(new TextBlock() //{ // Text = sprop.Name //}); wxToolBar.Items.Add(wxButton); } else if (elm == null) { wxToolBar.Items.Add(new Separator()); } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { //LimeMsg.Debug("LimeListView OnPropertyChanged: {0} : {1} : {2}", prop, prop.Ident, e?.PropertyName); if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Content") { LimePropertyCollection collec = null; if (typeof(LimePropertyCollection).IsAssignableFrom(prop.Type)) { collec = (LimePropertyCollection)prop.Content; } else { collec = new LimePropertyCollection(null, prop); } wxGridView.Columns.Clear(); // Create column definitons from a template first row if (collec.Count != 0) { var item = collec[0]; LimePropertyCollection items; if (item.Content is LimePropertyCollection col) { items = col; } else { items = new LimePropertyCollection(null, item.Content, prop); } GridViewColumn last = null; int idx = 0; foreach (var iprop in items) { var path = "Content" + (iprop.Ident != null ? string.Format(".{0}", iprop.Ident) : string.Format("[{0}]", idx) ); // Not a recommended way to make DataTemplate in code-behind, but this word // for this more-or-less static case. var datatemplate = new FrameworkElementFactory(typeof(LimeControl)); datatemplate.SetBinding(DataContextProperty, new Binding(path)); datatemplate.SetValue(OptionsEnabledProperty, false); datatemplate.SetValue(HeaderEnabledProperty, false); // Create the colum definition var gvcol = new GridViewColumn() { Header = iprop.Name, CellTemplate = new DataTemplate() { VisualTree = datatemplate } }; last = gvcol; wxGridView.Columns.Add(gvcol); idx++; } } wxList.DataContext = collec; } }
// -------------------------------------------------------------------------------------------------- #endregion // -------------------------------------------------------------------------------------------------- #region Methods /// <summary> /// Return a specialized <see cref="LimeControl"/> type matching the Type and attributes of a <see cref="LimeProperty"/>. /// </summary> /// <param name="prop">LimeProperty to be represented</param> /// <returns>LimeControl type selected to represent the LimeProperty properly</returns> public static Type LimeControlSelector(LimeProperty prop) { Type ret; var attrs = prop?.PInfo?.GetCustomAttributes(typeof(PickCollectionAttr), true); var type = prop?.Type; // Handle nullable types (example: bool?) if (type != null) { if (Nullable.GetUnderlyingType(type) is Type under) { type = under; } } if (prop == null) { ret = null; } else if (type == null) { ret = typeof(LimeLabel); } else if (typeof(ICommand).IsAssignableFrom(type)) { ret = typeof(LimeButton); } else if (typeof(LimePerson).IsAssignableFrom(type)) { ret = typeof(LimePersonCtrl); } else if (typeof(IStringComposite).IsAssignableFrom(type)) { ret = typeof(LimeTextBox); } else if (typeof(IPickCollection).IsAssignableFrom(type) || attrs != null && attrs.Length > 0) { ret = typeof(LimeDropDown); } else if (typeof(System.Drawing.Image).IsAssignableFrom(type) || typeof(ImageSource).IsAssignableFrom(type) || typeof(System.Drawing.Image).IsAssignableFrom(type) || typeof(TagLib.IPicture).IsAssignableFrom(type) || typeof(IEnumerable <System.Drawing.Image>).IsAssignableFrom(type) || typeof(IEnumerable <ImageSource>).IsAssignableFrom(type) || typeof(IEnumerable <TagLib.IPicture>).IsAssignableFrom(type)) { ret = typeof(LimeImage); } else if (typeof(IEnumerable).IsAssignableFrom(type) && type != typeof(string)) { // Find item type of a generic (for example T in Collection<T>) var itemType = type.GetInterfaces() .Where(t => t.IsGenericType && t.GetGenericTypeDefinition() == typeof(IEnumerable <>)) .Select(t => t.GenericTypeArguments.Length == 1 ? t.GenericTypeArguments[0] : null) .FirstOrDefault(); if (itemType != null && !typeof(IEnumerable).IsAssignableFrom(itemType) && itemType != typeof(object) && !typeof(LimeProperty).IsAssignableFrom(itemType)) { ret = typeof(LimeGridView); } else { ret = typeof(LimeListView); } } else if (prop.Minimum < prop.Maximum) { ret = typeof(LimeNumBox); } else if (type == typeof(bool)) { ret = typeof(LimeCheckBox); } else if (type == typeof(Color) || type == typeof(System.Drawing.Color)) { ret = typeof(LimeColorPicker); } else if (type.IsEnum || type == typeof(FontFamily) || type == typeof(FontWeight) || type == typeof(FontStyle)) { ret = typeof(LimeDropDown); } else if (type == typeof(byte) || type == typeof(short) || type == typeof(int) || type == typeof(long) || type == typeof(float) || type == typeof(double) || type == typeof(ushort) || type == typeof(uint) || type == typeof(ulong) ) { ret = typeof(LimeNumBox); } else if (type == typeof(string) || typeof(DateTime).IsAssignableFrom(type) || typeof(Uri).IsAssignableFrom(type)) { ret = typeof(LimeTextBox); } else { ret = typeof(LimeComposite); } return(ret); }
/// <summary> /// Trigger on Change of the associated LimeProperty /// </summary> /// <param name="prop">LimeProperty assiociated with the control, cannot be null</param> /// <param name="e">PropertyChangedEventArgs, e.PropertyName==null if property initialization</param> protected virtual void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { }
private static void OnBoundDataContextChanged(DependencyObject d, DependencyPropertyChangedEventArgs e) { var wxThis = d as LimeControl; var isLimeControl = wxThis != null && wxThis.GetType() == typeof(LimeControl); //LimeMsg.Debug("LimeControl OnBoundDataContextChanged: {0}", e.NewValue); if (e.OldValue is LimeProperty old) { old.PropertyChangedWeak -= wxThis.TriggerDataContextChanged; } var prop = e.NewValue as LimeProperty; var content = prop != null ? prop.Content : e.NewValue; // Unpack from Matryoshka if (content is IMatryoshka matr) { // Find the most inner matryoshka object while (matr.Content is IMatryoshka sub) { matr = sub; } content = matr.Content; // Repack into a LimeProperty if (prop != null) { prop = new LimeProperty(null, matr, "Content", prop); } else { prop = new LimeProperty(null, matr, "Content"); } } // Encapsulate into LimeProperty if (prop == null && content != null) { prop = new LimeProperty(null, content); e = new DependencyPropertyChangedEventArgs(e.Property, e.OldValue, prop); } // Select the right LimeControl sub-class depending on the Type of the LimeProperty LimeControl wxbind = wxThis; if (isLimeControl) { #if DEBUG wxThis.ADebug = prop != null?string.Format("{1} [{0}] (base)", prop.Type, prop.Ident ?? prop.Name) : "null (base)"; #endif // Type dispatcher var type = LimeControlSelector(prop); LimeControl wxobj = null; if (type == null) { // do nothing } else if (type != wxThis.Content?.GetType()) { wxobj = (LimeControl)Activator.CreateInstance(type); wxobj.Base = wxThis; } else { wxobj = (LimeControl)wxThis.Content; } wxThis.Content = wxbind = wxobj; #if DEBUG if (wxobj != null) { wxobj.ADebug = prop != null?string.Format("{1} [{0}] (content)", prop.Type, prop.Ident ?? prop.Name) : "null (content)"; } #endif } // Bind property to this Control (or content) if (prop != null) { prop.PropertyChangedWeak += wxbind.TriggerDataContextChanged; } if (wxThis != null && wxThis.Content is FrameworkElement wxcont) { wxcont.DataContext = prop; } // Event trigger wxbind?.OnBoundDataContextChanged(e); if (!isLimeControl && wxbind != null) { // Trigger Binding initialization wxbind.TriggerDataContextChanged(prop, new PropertyChangedEventArgs(null)); } }
/// <summary> /// Handle the Command Line Interface parsing of the application. /// </summary> /// <param name="firstInstance">true if this is the first instance, false if the application is re-opened</param> /// <param name="args">list of arguments of the command</param> /// <returns>true if handled.</returns> public bool CommandLineInterface(bool firstInstance, IList <string> args) { LimeMsg.Debug("CommandLineInterface: {0}", firstInstance); Global.Local.CtrlMode = CtrlMode.CLI; for (int i = firstInstance ? 0 : 1; i < args.Count; i++) { LimeMsg.Debug("CommandLineInterface: {0}: arg: {1}", firstInstance, args[i]); string arg = args[i]; if (arg.Length > 0) { // Options LimeProperty prop = null; bool isToggle = false; // Parse argument (detect = and !) string value = null; int idx = arg.IndexOf('='); if (idx >= 0) { value = arg.Substring(idx + 1); arg = arg.Substring(0, idx).Trim(); } else if (arg.EndsWith("!")) { isToggle = true; arg = arg.Substring(0, arg.Length - 1).Trim(); } if ((prop = Global.Properties.Get(arg)) != null) { // Property if (value != null) { if (prop.ReadOnly) { LimeMsg.Error("ErrReadOnlyProp", args[i]); } else { try { prop.Serialize = value; } catch { LimeMsg.Error("ErrInvProp", args[i], prop.Type.ToString()); } } } else if (isToggle) { prop.Toggle(); } else if (prop.Content is LimeCommand cmd) { cmd.Execute(); } } else { // Other options bool handled = true; switch (arg.ToLower()) { case "?": case "h": case "help": { // TODO: do something usefull here Console.WriteLine("hello"); break; } default: handled = false; break; } // Try Skin-parameters if (!handled && Global.Local.Skin != null) { var param = Global.Local.Skin.Get(arg); if (param != null) { if (param.Visible && param.Content != null) { handled = true; if (value != null) { try { param.Serialize = value; } catch { LimeMsg.Error("ErrInvSkinProp", args[i], param.Type.ToString()); } } break; } } } // No match found if (!handled) { LimeMsg.Error("ErrInvArg", args[i]); } } } } return(true); }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Icon" || e.PropertyName == "Type") { // Free previous resources of the control if (Content is ButtonBase wxobj) { wxobj.PreviewKeyDown -= FixFocus_PreviewKeyDown; wxobj.IsEnabledChanged -= Button_IsEnabledChanged; } // Create the Content of the wxMain Border: // <ButtonBase ToolTip="{Binding Desc}" PreviewKeyDown="FixFocus_PreviewKeyDown"> // <StackPanel x:Name="wxPanel" Orientation="Horizontal"> // </StackPanel> // </ButtonBase> ButtonBase wxButton; if (prop.Type == typeof(bool) || prop.Type == typeof(bool?)) { wxButton = new ToggleButton(); wxButton.SetBinding(ToggleButton.IsCheckedProperty, new Binding("Content")); } else { wxButton = new Button(); wxButton.SetBinding(ButtonBase.CommandProperty, new Binding("Content")); } wxButton.SetBinding(ToolTipProperty, new Binding("Desc")); wxButton.PreviewKeyDown += FixFocus_PreviewKeyDown; wxButton.IsEnabledChanged += Button_IsEnabledChanged; wxButton.Content = new StackPanel() { Orientation = Orientation.Horizontal }; wxMain.Child = wxButton; } var wxPanel = (Panel)((ButtonBase)wxMain.Child).Content; if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Name" || e.PropertyName == "ReqAdmin" || e.PropertyName == "ReqRestart" || e.PropertyName == "Icon") { wxPanel.Children.Clear(); if (prop.ReqAdmin) { wxPanel.Children.Add(new LimeIcon() { IconKey = "Shield", ToolTip = LimeLanguage.Translate(LanguageSection, "ShieldTip", "ShieldTip") }); } if (prop.ReqRestart) { wxPanel.Children.Add(new LimeIcon() { IconKey = "Warning", ToolTip = LimeLanguage.Translate(LanguageSection, "RestartTip", "RestartTip") }); } if (!string.IsNullOrEmpty(prop.Icon)) { wxPanel.Children.Add(new LimeIcon() { IconKey = prop.Icon }); } wxPanel.Children.Add(new TextBlock() { Text = prop.Name }); } }
protected override void OnPropertyChanged(LimeProperty prop, PropertyChangedEventArgs e) { if (string.IsNullOrEmpty(e.PropertyName)) { wxValidation.Source = prop; } if (prop == null) { // do nothing } else if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Value" || e.PropertyName == "Percentage" || e.PropertyName == "Maximum" || e.PropertyName == "Minimum" || e.PropertyName == "ReadOnly" || e.PropertyName == "AllowEmpty") { var min = prop.Minimum; var max = prop.Maximum; if (min < max && !prop.ReadOnly) { wxCol.Width = new GridLength(1, GridUnitType.Star); wxSlider.Visibility = Visibility.Visible; if (prop.Percentage) { min *= 100; max *= 100; } wxSlider.Minimum = min; wxSlider.Maximum = max; } else { wxCol.Width = new GridLength(0); wxSlider.Visibility = Visibility.Collapsed; } wxMinus.Visibility = prop.ReadOnly ? Visibility.Collapsed : Visibility.Visible; wxPlus.Visibility = wxMinus.Visibility; if (string.IsNullOrEmpty(e.PropertyName) || e.PropertyName == "Value") { if (!prop.Percentage && (prop.Type == typeof(float) || prop.Type == typeof(double))) { var diff = max - min; wxSlider.SmallChange = diff > 20 ? 1 : diff > 1 ? 0.1 : diff > 0 ? diff / 100 : 0.01; } else { wxSlider.SmallChange = 1; } wxSlider.LargeChange = wxSlider.SmallChange * 10; if (prop.AllowEmpty && prop.Value == "") { wxTextBox.Text = ""; } else if (double.TryParse(prop.Value, out double val)) { if (prop.Percentage) { val *= 100; } if (wxSlider.Visibility == Visibility.Visible) { wxSlider.Value = val; } else { wxTextBox.Text = val.ToString() + (prop.Percentage && !wxTextBox.IsFocused ? "%" : ""); } } } } }