Использование StringConverter для отображения списка в сетке свойств. Работает только во время выполнения - PullRequest
0 голосов
/ 08 ноября 2019

Я создаю очень простую систему тем. В одном из моих пользовательских элементов управления я хочу отобразить список тем, хранящихся в файле. Код ниже работает. Но, только отображает список во время выполнения. Я знаю. Потому что у меня есть этот элемент управления, связанный с сеткой свойств. Но мне нужно, чтобы пользователь мог выбрать тему в режиме дизайна. Я предполагаю, что это потому, что вы не можете выполнить вызов Task.Run ().

Примечание. Я использую async / await, поскольку файл может храниться в сети или в Интернете.

Редактировать: Добавлен мой текущий класс ThemeLoader

class SelectedObjectConverter : StringConverter
{
    public static StandardValuesCollection StringObjects =
        new StandardValuesCollection(new string[0]);

    public override bool GetStandardValuesSupported(
        ITypeDescriptorContext context) => true;

    public override StandardValuesCollection GetStandardValues(
        ITypeDescriptorContext context) => StringObjects;
}

private string _Themes = NONE;
[Category("Custom"), Description(""), DefaultValue("(none)"),
    TypeConverter(typeof(SelectedObjectConverter))]
public string Themes
{
    get
    {
        SelectedObjectConverter.StringObjects = new SelectedObjectConverter.
            StandardValuesCollection(Task.Run(async () =>
            await GetThemeNames("testjson.txt")).Result);

        return _Themes;
    }
    set
    {
        _Themes = value;
    }
}

Свойство темы во время разработки:

enter image description here

Свойство темы во время выполнения:

enter image description here

Запуск класса ThemeLoaderздесь:

#region Copyright notice and license
/*The MIT License(MIT)
Copyright(c), Tobey Peters, https://github.com/tobeypeters
...
*/
#endregion
using System;
using System.Collections.Generic;
using System.Diagnostics;
using System.Drawing;
using System.Threading.Tasks;
using System.Web.Script.Serialization;
using System.Linq;
using static misc;

public static class ThemeLoader
{
    public interface ITheme { public Task<bool> ApplyTheme(); }

    public class Theme
    {
        /// <summary> Class definition for Custom Color Themes.
        /// This class can be easily altered, to meet your needs. </summary>
        public string Name { get; set; }
        public Color Primary_Background { get; set; }
        public Color Secondary_Background { get; set; }
        public Color Tertiary_Background { get; set; }
        public Color Arrow_Normal { get; set; }
        public Color Arrow_Down { get; set; }
        public Color Arrow_Hover { get; set; }
        public Color Border_Normal { get; set; }
        public Color Edge_Normal { get; set; }
        public Color Edge_Light { get; set; }
        public Color Edge_Dark { get; set; }
        public Color Gutter_Normal { get; set; }
        public Color Gutter_Hover { get; set; }
        public Color Thumb_Normal { get; set; }
        public Color Thumb_Down { get; set; }
        public Color Thumb_Hover { get; set; }
    }

    private const string DefaultThemeFIle = "Themes.json";

    private static async Task<List<Theme>> GetThemes(
        string inFile = DefaultThemeFIle)
        => (FileExists(inFile) ? new JavaScriptSerializer()
        .Deserialize<List<Theme>>(await ReadTextAsync(inFile)) : null);

    /// <summary> Get the Color values of a named Theme. </summary>
    public static async Task<Theme> GetValuesForTheme(string inTheme,
        string inFile = DefaultThemeFIle)
    {
        List<Theme> buffer = await GetThemes(inFile);

        return ((buffer != null) ?
            (Theme)(from i in buffer where i.Name == inTheme select i.Name) : null);
    }

    public static async Task<string[]> GetThemeNames(
        string inFile = DefaultThemeFIle)
    {
        List<Theme> buffer = await GetThemes(inFile);

        return ((buffer != null) ?
            (from i in buffer select i.Name).ToArray() : new string[0]);
    }
}
...