These are chat archives for AvaloniaUI/Avalonia

24th
Aug 2018
cm4ker
@cm4ker
Aug 24 2018 06:09
Hi folks!
I continue investigation around xaml loading
Today I found strange behavour
For example:
<Window Height="400" Width="300" xmlns="https://github.com/avaloniaui">
  <Window.Content>
   <DataGrid xmlns="clr-namespace:Avalonia.Controls;assembly=Avalonia.DataGrid">
          <DataGrid.Columns>
            <DataGridTextColumn Header="Test" />
            </DataGrid.Columns>
        </DataGrid>
   </Window.Content>
</Window>
I need force set datagrid xmlns to clr-namespace
But dataagrid control assembly have this:
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls")]
[assembly: XmlnsDefinition("https://github.com/avaloniaui", "Avalonia.Controls.Primitives")]
i've not investigated why it doesn't work yet
cm4ker
@cm4ker
Aug 24 2018 09:51
@grokys ok, I try to investigate this issue
thank you
Sergey
@PurpleGray
Aug 24 2018 11:41
Is there any example how to bind to Enum values from xaml?
Sergey
@PurpleGray
Aug 24 2018 11:47
Ok, no need, fixed wpf-way to work in my case
Wiesław Šoltés
@wieslawsoltes
Aug 24 2018 12:23
@Stratocast3r Could you share your solution
I do something like this
public static LineCap[] LineCapValues { get; } = (LineCap[])Enum.GetValues(typeof(LineCap));
Items="{x:Static Editor:Enums.LineCapValues}" SelectedItem="{Binding LineCap, Mode=TwoWay}"
Sergey
@PurpleGray
Aug 24 2018 13:00
  1. MarkupExtension:
public class EnumToItemsSource : MarkupExtension
{
    private readonly Type _type;

    public EnumToItemsSource(Type type)
    {
        _type = type;
    }

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return Enum.GetValues(_type)
            .Cast<object>()
            .Select(e => GetDescription((Enum)e)).ToList();
    }

    private static string GetDescription(Enum value)
    {
        var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attributes.Any())
            return (attributes.First() as DescriptionAttribute).Description;

        // If description not found
        return value.ToString();
    }
}
In enum you can use [Description("...")] attr
  1. Xaml:
Items="{utils:EnumToItemsSource {markup:Type enums:ActivityType}}"
But your solution is better in some ways, because SelectedItem is works
Sergey
@PurpleGray
Aug 24 2018 13:09
You solution can be modified via some converter that will try to get Description of provided enum value
So actually I will borrow your approach + add converter :)
Wiesław Šoltés
@wieslawsoltes
Aug 24 2018 13:10
no problem :smile:
please share you version with converter, so I may also use it :smile:
Sergey
@PurpleGray
Aug 24 2018 13:20
public class EnumDescriptionConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value is Enum enumVal)
        {
            return GetDescription(enumVal);
        }

        return string.Empty;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }

    private static string GetDescription(Enum value)
    {
        var attributes = value.GetType().GetField(value.ToString()).GetCustomAttributes(typeof(DescriptionAttribute), false);
        if (attributes.Any())
            return (attributes.First() as DescriptionAttribute).Description;

        // If description not found
        return value.ToString();
    }
}
Then in any ItemControl apply it:
          <DropDown.ItemTemplate>
            <DataTemplate>
              <TextBlock Text="{Binding Converter={StaticResource EnumDescriptionConv}}" />
            </DataTemplate>
          </DropDown.ItemTemplate>
public enum ActivityType
{
    [Description("Device")]
    [EnumMember(Value = "device")]
    DeviceActivity,
    [Description("Other")]
    [EnumMember(Value = "other")]
    OtherActivivty
}
Benedikt Schroeder
@Gillibald
Aug 24 2018 13:22
This is how I do it:
public class EnumViewModel : ViewModelBase, IEnumerable
    {
        private Type _enumType;
        private IEnumerable _values;

        public IEnumerable Values
        {
            get => _values;
            protected set
            {
                _values = value;
                RaisePropertyChanged();
            }
        }

        public EnumViewModel()
        {
            _values = Enumerable.Empty<string>();
        }

        public Type EnumType
        {
            get => _enumType;
            set
            {
                _enumType = value;
                RaisePropertyChanged();
                InitValues();
            }
        }

        private void InitValues()
        {
            Values = EnumType.GetFields(BindingFlags.Public | BindingFlags.Static).Select(x => x.GetValue(EnumType));
        }


        public IEnumerator GetEnumerator()
        {
            return Values.GetEnumerator();
        }
    }
Benedikt Schroeder
@Gillibald
Aug 24 2018 13:28
<viewModel:EnumViewModel x:Key="VisualAlignments" EnumType="{x:Type types:VisualAlignment}"/>