Могу ли я настроить предложения IntelliSense, которые зависят от другого свойства? - PullRequest
0 голосов
/ 01 июля 2018

Хорошо, это, вероятно, наивный вопрос, но я хочу получить предложения IntelliSense для свойства для нескольких перечислений. Что ж. Своего рода. Но позвольте мне объяснить.

У меня есть пара перечислений, вот так

public static class Icons 
{
    public enum Regular { /* ... */ }
    public enum Solid{ /* ... */ }
    public enum Brands { /* ... */ }
}

public enum Styles { /* ... */ }

Теперь я получил элемент управления XAML с двумя DependencyProperties

public static readonly DependencyProperty MyStyleProperty = DependencyProperty.Register(nameof(MyStyle), typeof(Styles), typeof(Icon), new FrameworkPropertyMetadata(Styles.None, FrameworkPropertyMetadataOptions.AffectsRender, OnUpdateControl));

public static readonly DependencyProperty MyIconProperty = DependencyProperty.Register(nameof(MyIcon), typeof(object), typeof(Icon), new FrameworkPropertyMetadata(null, FrameworkPropertyMetadataOptions.AffectsRender, OnUpdateControl));

Control.Style принимает значения из перечисления Styles.
Control.Icon принимает значения Icons.[Regular, Solid, Brands].

Предложения IntelliSense для Icon зависят от выбранного Style. Поэтому, если Control.Style равно Styles.Regular, отображаются только предложения для Icons.Regular на Control.Icon.

1 Ответ

0 голосов
/ 02 июля 2018

Теоретически возможно добавить CompletionProvider, который позволил бы Intellisense обрабатывать ваш отдельный класс, но это было бы излишним для такой распространенной проблемы. Вместо этого используйте класс enum или классы категорий.

Класс Enum (не совсем, поскольку конструктор является общедоступным, но в этом случае его открытие кажется логичным):

public sealed class IconImage
{
    public Uri ImageUri { get; }
    public IconImage(Uri imageUri)
    {
        this.ImageUri = imageUri;
    }

    public static class ApplicationActions
    {
        public readonly IconImage Save = new IconImage(new Uri("foo"));
        public readonly IconImage Open = new IconImage(new Uri("foo"));
        public readonly IconImage Print = new IconImage(new Uri("foo"));
    }

    public static class Marks
    {
        public readonly IconImage Check = new IconImage(new Uri("foo"));
        public readonly IconImage Tickbox = new IconImage(new Uri("foo"));
        public readonly IconImage CheckedTickbox = new IconImage(new Uri("foo"));
    }

    // ...
}

// Usage: control.Icon = IconImage.Marks.TickBox;
// XAML (without TypeConverter): Icon="{x:Static local:IconImage.Marks.TickBox}"
// XAML (with TypeConverter): Icon="Marks.TickBox"

Категория Классы:

public enum IconImage
{
    Save, Open, Print,
    Check, Tickbox, CheckedTickbox,
    // ...
}

public static class IconImages
{
    public static class Application
    {
        public static readonly IconImage
            Save = IconImage.Save,
            Open = IconImage.Open,
            Print = IconImage.Print;
    }

    public static class Marks
    {
        public static readonly IconImage
            Check = IconImage.Check,
            Tickbox = IconImage.Tickbox,
            CheckedTickbox = IconImage.CheckedTickbox;
    }

    // … other category classes …
}

// Usage: control.Icon = IconImage.Print  -- or --  control.Icon = IconImages.Application.Print
// XAML: Icon="Print" -- or -- Icon="{x:Static local:IconImages.Application.Print}"

Для любого маршрута я бы предложил использовать такой инструмент, как T4 или XSLT, для динамической генерации кода. При ручном ведении больших списков очень легко вносить ошибки.

...