UI - Replaced tuples with custom classes for binding

As far as i know, it's not possible to have CompiledBindings with tuples, since tuple values are fields and not properties. This change allows for compiled bindings, and makes the intent behind the tuples clearer
This commit is contained in:
Diogo Trindade committed 2023-04-30 21:40:36 +01:00
1 parent 59f9479d9a
commit 5429346396
9 files changed
+120 -45

No files matched your search

@@ -3,11 +3,12 @@
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d" d:DesignWidth="800" d:DesignHeight="450"
xmlns:local="clr-namespace:Artemis.UI.Shared"
x:Class="Artemis.UI.Shared.EnumComboBox">
<ComboBox x:Name="ChildEnumComboBox" HorizontalAlignment="Stretch">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding [1]}" />
<DataTemplate x:DataType="local:EnumComboBoxItem">
<TextBlock Text="{CompiledBinding Value}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
@@ -20,11 +20,9 @@ public partial class EnumComboBox : UserControl
/// </summary>
public static readonly StyledProperty<object?> ValueProperty = AvaloniaProperty.Register<EnumComboBox, object?>(nameof(Value), defaultBindingMode: BindingMode.TwoWay);
private readonly ObservableCollection<(Enum, string)> _currentValues = new();
private readonly ObservableCollection<EnumComboBoxItem> _currentValues = new();
private Type? _currentType;
private ComboBox? _enumComboBox;
/// <summary>
/// Creates a new instance of the <see cref="EnumComboBox" /> class.
/// </summary>
@@ -54,35 +52,35 @@ public partial class EnumComboBox : UserControl
private void OnSelectionChanged(object? sender, SelectionChangedEventArgs e)
{
if (_enumComboBox == null || _enumComboBox.SelectedIndex == -1)
if (ChildEnumComboBox == null || ChildEnumComboBox.SelectedIndex == -1)
return;
(Enum enumValue, _) = _currentValues[_enumComboBox.SelectedIndex];
if (!Equals(Value, enumValue))
Value = enumValue;
EnumComboBoxItem v = _currentValues[ChildEnumComboBox.SelectedIndex];
if (!Equals(Value, v.Value))
Value = v.Value;
}
private void UpdateValues()
{
Type? newType = Value?.GetType();
if (_enumComboBox == null || newType == null || _currentType == newType)
if (ChildEnumComboBox == null || newType == null || _currentType == newType)
return;
_currentValues.Clear();
foreach ((Enum, string) valueDesc in EnumUtilities.GetAllValuesAndDescriptions(newType))
_currentValues.Add(valueDesc);
_currentValues.Add(new EnumComboBoxItem(value: valueDesc.Item1, description: valueDesc.Item2));
_currentType = newType;
}
private void UpdateSelection()
{
if (_enumComboBox == null || Value is not Enum)
if (ChildEnumComboBox == null || Value is not Enum)
return;
(Enum, string) value = _currentValues.FirstOrDefault(v => v.Item1.Equals(Value));
if (!Equals(value.Item1, _enumComboBox.SelectedItem))
_enumComboBox.SelectedItem = value;
EnumComboBoxItem? value = _currentValues.FirstOrDefault(v => v.Value.Equals(Value));
if (!Equals(value?.Value, ChildEnumComboBox.SelectedItem))
ChildEnumComboBox.SelectedItem = value;
}
#region Overrides of TemplatedControl
@@ -90,12 +88,11 @@ public partial class EnumComboBox : UserControl
/// <inheritdoc />
protected override void OnAttachedToLogicalTree(LogicalTreeAttachmentEventArgs e)
{
_enumComboBox = this.Get<ComboBox>("ChildEnumComboBox");
_enumComboBox.ItemsSource = _currentValues;
ChildEnumComboBox.ItemsSource = _currentValues;
UpdateValues();
UpdateSelection();
_enumComboBox.SelectionChanged += OnSelectionChanged;
ChildEnumComboBox.SelectionChanged += OnSelectionChanged;
base.OnAttachedToLogicalTree(e);
}
@@ -103,11 +100,36 @@ public partial class EnumComboBox : UserControl
/// <inheritdoc />
protected override void OnDetachedFromLogicalTree(LogicalTreeAttachmentEventArgs e)
{
if (_enumComboBox != null)
_enumComboBox.SelectionChanged -= OnSelectionChanged;
if (ChildEnumComboBox != null)
ChildEnumComboBox.SelectionChanged -= OnSelectionChanged;
base.OnDetachedFromLogicalTree(e);
}
#endregion
}
/// <summary>
/// Represents an item in the <see cref="EnumComboBox" />
/// </summary>
public class EnumComboBoxItem
{
/// <summary>
/// Creates a new instance of the <see cref="EnumComboBoxItem" /> class.
/// </summary>
public EnumComboBoxItem(Enum value, string description)
{
Value = value;
Description = description;
}
/// <summary>
/// Gets or sets the value of the item
/// </summary>
public Enum Value { get; set; }
/// <summary>
/// Gets or sets the description of the item
/// </summary>
public string Description { get; set; }
}