Оператор Switch (Select) в привязке Xaml?

Juan,

мне нравится думать об интерфейсах как о способе характеризовать класс. Конкретный класс породы собак, скажем YorkshireTerrier, может быть убывавшим из родительского класса собаки, но это - также реализации IFurry, IStubby и IYippieDog. Таким образом, класс определяет то, что класс является всего лишь интерфейсом, говорит нам вещи об этом.

преимущество этого - он, позволяет мне, например, соберите весь IYippieDog и бросьте их в мой Океанский набор. Таким образом, теперь я могу достигнуть через определенный набор объектов и найти, которые соответствуют критериям, на которые я смотрю, не осматривая класс слишком тесно.

я нахожу, что интерфейсы действительно должны определить подмножество общедоступного поведения класса. Если это определяет все общедоступное поведение для всех классов, которые реализуют тогда, это обычно не должно существовать. Они не говорят мне ничего полезного.

Эта мысль, хотя идет в противоречии с идеей, что каждый класс должен иметь интерфейс и необходимо кодировать к интерфейсу. Это прекрасно, но Вы заканчиваете с большим количеством одного, каждый взаимодействует через интерфейс к классам, и оно делает вещи, путающие. Я понимаю, что идея - он, действительно не стоит ничего, чтобы сделать, и теперь можно загрузить вещи и легко. Однако я нахожу, что редко делаю это. Большую часть времени я просто изменяю существующий класс на месте и имею те же самые проблемы, которые я всегда делал, если для открытого интерфейса того класса нужно изменение, кроме я теперь должен изменить его в двух местах.

Поэтому, если бы Вы думаете как я, что определенно сказали бы, что CAT и Собака являются IPettable. Это - характеристика, которая соответствует им обоим.

другая часть этого, хотя, у них должен быть тот же базовый класс? Вопрос, делают их нужно широко рассматривать как то же самое. Конечно, они - оба Животные, но делает то соответствие, как мы собираемся использовать их вместе.

Говорят, что я хочу собрать все классы Животных и поместить их в мой контейнер Ковчега.

Или они должны быть Млекопитающими? Возможно, нам нужно некоторое перекрестное животное, доящее фабрику?

они должны даже быть соединены вообще? Достаточно просто знать, что они - оба IPettable?

я часто чувствую требование получить целую иерархию классов, когда мне действительно просто нужен один класс. Я делаю это в ожидании когда-нибудь, мне, возможно, понадобился бы он, и обычно я никогда не делаю. Даже когда я делаю, я обычно нахожу, что должен сделать много для фиксации его. That’s, потому что первый класс я создаю, не является Собакой, я не настолько удачлив, это - вместо этого Утконос. Теперь моя вся иерархия классов основана на причудливом случае, и у меня есть много потраченного впустую кода.

Вы могли бы также найти в какой-то момент, что не все Кошки являются IPettable (как этот лысый). Теперь можно переместить тот Интерфейс во все производные классы то соответствие. Вы найдете, что намного меньше повреждающегося изменения, что внезапно Кошки больше не получаются из PettableBase.

7
задан Shimmy 6 December 2010 в 13:55
поделиться

1 ответ

Я сделал упрощенный, обновленный преобразователь на основе принятого ответа. Это также позволяет сравнению строк и случаю по умолчанию быть установленным:

[ContentProperty("Cases")]
public class SwitchConverter : IValueConverter
{
    public SwitchConverter()
    {
        Cases = new List<SwitchConverterCase>();
    }

    public List<SwitchConverterCase> Cases { get; set; }

    public StringComparison StringComparisonType { get; set; } = StringComparison.InvariantCulture;

    public object Default { get; set; }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        if (value == null || Cases == null)
        {
            return DependencyProperty.UnsetValue;
        }

        SwitchConverterCase result = Cases.FirstOrDefault(c => string.Equals(value.ToString(), c.When, StringComparisonType));
        return result != null ? result.Then : Default;
    }

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

SwitchConverterCase класс:

[ContentProperty("Then")]
public class SwitchConverterCase
{
    public SwitchConverterCase()
    {
    }

    public SwitchConverterCase(string when, object then)
    {
        When = when;
        Then = then;
    }

    public string When { get; set; }

    public object Then { get; set; }

    public override string ToString() => $"When={When}; Then={Then}";
}

использование В качестве примера:

<con:SwitchConverter x:Key="StyleConverter"
                     Default="{x:Static FontWeights.Normal}">
    <con:SwitchConverterCase When="pageHeader"
                             Then="{x:Static FontWeights.Bold}" />
    <con:SwitchConverterCase When="header"
                             Then="{x:Static FontWeights.SemiBold}" />
    <con:SwitchConverterCase When="smallText"
                             Then="{x:Static FontWeights.Light}" />
    <con:SwitchConverterCase When="tinyText"
                             Then="{x:Static FontWeights.Thin}" />
</con:SwitchConverter>

<TextBlock FontWeight="{Binding Style, Converter={StaticResource StyleConverter}}" />

Или встроенный:

<TextBlock>
    <TextBlock.FontWeight>
        <Binding Path="Style">
            <Binding.Converter>
                <con:SwitchConverter Default="{x:Static FontWeights.Normal}">
                    <con:SwitchConverterCase When="pageHeader"
                                             Then="{x:Static FontWeights.Bold}" />
                    <!-- etc -->
                </con:SwitchConverter>
            </Binding.Converter>
        </Binding>
    </TextBlock.FontWeight>
</TextBlock>
0
ответ дан 6 December 2019 в 09:15
поделиться
Другие вопросы по тегам:

Похожие вопросы: