Чи є у XAML умовна директива компілятора для режиму налагодження?


76

Мені потрібно щось подібне для стилів у XAML:

<Application.Resources>

#if DEBUG
    <Style TargetType="{x:Type ToolTip}">
        <Setter Property="FontFamily" Value="Arial"/>
        <Setter Property="FlowDirection" Value="LeftToRight"/>
    </Style>
#else
    <Style TargetType="{x:Type ToolTip}">
        <Setter Property="FontFamily" Value="Tahoma"/>
        <Setter Property="FlowDirection" Value="RightToLeft"/>
    </Style>
#endif

</Application.Resources>

2
Що ви намагаєтесь досягти?
— tsells

2
Мені потрібно мати різні стилі в режимі налагодження, щоб я міг зробити легше виконання в режимі налагодження.
— Ehsan Zargar Ershadi

Відповіді:


125

Нещодавно мені довелося це зробити, і я був здивований тим, наскільки просто це було, коли я не міг легко знайти чітких прикладів. Що я зробив, це додав наступне до AssemblyInfo.cs:

#if DEBUG
[assembly: XmlnsDefinition( "debug-mode", "Namespace" )]
#endif

Потім, використовуйте тег AlternateContent для простори імен розмітки, що відповідає сумісності, щоб вибрати вміст на основі презентації цього простору імен:

<Window x:Class="Namespace.Class"
        xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
        xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"

        xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
        xmlns:d="debug-mode"

        Width="400" Height="400">

        ...

        <mc:AlternateContent>
            <mc:Choice Requires="d">
                <Style TargetType="{x:Type ToolTip}">
                    <Setter Property="FontFamily" Value="Arial"/>
                    <Setter Property="FlowDirection" Value="LeftToRight"/>
                </Style>
            </mc:Choice>
            <mc:Fallback>
                <Style TargetType="{x:Type ToolTip}">
                    <Setter Property="FontFamily" Value="Tahoma"/>
                    <Setter Property="FlowDirection" Value="RightToLeft"/>
                </Style>
            </mc:Fallback>
        </mc:AlternateContent>

        ...
</Window>

Тепер, коли визначено DEBUG, буде також визначено "режим налагодження", і буде присутній простір імен "d". Це змушує тег AlternateContent вибрати перший блок коду. Якщо DEBUG не визначено, буде використаний резервний блок коду.

Цей зразок коду не тестувався, але в основному це те саме, що я використовую у своєму поточному проекті, щоб умовно показати деякі кнопки налагодження.

Я бачив допис у блозі з прикладом коду, який спирався на тег "Ігнорується", але це здавалося набагато менш зрозумілим та простим у використанні як цей метод.


5
Панелі помилок VS це не подобається, хоча все працює
— належним чином

1
Моє рішення не вдається скомпілювати, коли я додаю код до AssemblyInfo.cs. Я розумію The type or namespace name 'XmlnsDefinitionAttribute' could not be found (are you missing a using directive or an assembly reference?). Що я можу зробити?
— nimbudew

1
XmlnsDefinitionAttributeзнаходиться у System.Windows.Markupпросторі імен. Цей простір імен знаходиться у System.Xaml.dllзбірці, яка, на мою думку, додається автоматично при створенні проекту WPF у Visual Studio.
— bj0,

1
Якщо ви використовуєте функцію між AlternateContent, яка додає код до методу IComponentConnector.Connect (обробники подій, як OnClick do), то ідентифікатори з'єднання повністю збиваються, і InitializeComponent або вийде з ладу під час виконання, або зробить несподівані дії (перемішайте обробники подій).
— springy76

5
Зверніть увагу, що вам може знадобитися позначити "mc" Неприпустимим проти себе, тобто mc: Ignorable = "d mc"
— JulieC

2

Ви можете скористатися засобом вибору шаблону. Клас DataTemplateSelector - це те, що ви кодуєте. За допомогою методу вибору шаблону, який ви перевизначаєте, ви можете розмістити директиви препроцесора.

http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx


A DataTemplateSelectorможе бути доречним, якщо питання стосувалось змісту альтернативного перегляду , але мова йде про альтернативні стилі - для альтернативних стилів не існує "селектора". Ну, ви можете створити дві окремі копії вмісту, використовуючи різні стилі ... але це не схоже на те, що ви намагаєтесь сказати тут.
— ToolmakerSteve

2

Це неможливо в WPF / Silverlight / WP7.

Цікаво відзначити, що стандартний документ, ISO / IEC 29500 , висвітлює, як з цим слід поводитися в XML-документі, а XAML підтримує один із елементів із цієї специфікації, mc:Ignorableщо дозволяє нам робити такі речі:

<Page xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
      xmlns:c="Comments"
      mc:Ignorable="c">
    <Button Content="Some Text"
            c:Content="Some other text" />
</Page>

коментувати атрибути. Я думаю, було б круто, якби XAML одного дня підтримував решту специфікацій, що дозволяють завантажувати альтернативний вміст.

mc:IgnorableАтрибут використовується Blend , функціональності підтримки у час розробки.


1
Яке відношення специфікації формату файлу MS OFfice Open XML до XAML?
— Ніколас Кері

Танки, але ця проблема не відповідає моїй ситуації.
— Ehsan Zargar Ershadi

Ніколас, команда аналізатора XAML (SL4, WP7.1, WPF) вирішила використовувати цю специфікацію для вирішення своїх потреб в ігноруванні атрибутів, а не просто для вигадування чогось. Ось чому деякі сторінки XAML за замовчуванням мають визначений простір імен 'mc'.
— JasonRS Shaver

1

Я відчуваю, що подані відповіді не найпростіші у використанні. Ось моє рішення з використанням спеціальної властивості залежності, що приєднується:

using namespace Utility{
    public static class DebugVisibility
    {
        public static readonly DependencyProperty IsVisibleProperty = DependencyProperty.RegisterAttached(
    "Debug", typeof(bool?), typeof(DebugVisibility), new PropertyMetadata(default(bool?), IsVisibleChangedCallback));

        private static void IsVisibleChangedCallback(DependencyObject d, DependencyPropertyChangedEventArgs e)
        {
            var fe = d as FrameworkElement;
            if (fe == null)
                return;
#if DEBUG
            fe.Visibility = Visibility.Visible;
#else
            fe.Visibility = Visibility.Collapsed;
#endif
        }

        public static void SetIsVisible(DependencyObject element, bool? value)
        {
            element.SetValue(IsVisibleProperty, value);
        }

        public static bool? GetIsVisible(DependencyObject element)
        {
            return (bool?)element.GetValue(IsVisibleProperty);
        }
    }
}

і xaml буде використовуватися так:

<window ... xmlns:Util="clr-namespace:MyNamespace.Utility" >
    <Label Util:DebugVisibility.IsVisible="True">
</window>

Я вважав це булітом на випадок, якщо ви хочете додати туди іншу логіку видимості. Це хороший простий перемикач, який можна прив’язати до будь-якого елемента керування та прикріпити до нього


Хороша ідея, але реалізація може бути набагато простішою. Налагодження / випуск, очевидно, не змінюється в середині циклу, тому вам не потрібні всі матеріали зв’язування / залежності. Все, що вам потрібно, це статична змінна "Налагодження" в Util, тобто True при налагодженні та False, коли ні. (І для зручності, другий статичний "Випуск", який є помилковим при налагодженні.) Тоді зробіть <Label IsVisible={Static Util:Debug}.
— ToolmakerSteve

1
ПРИМІТКА. Ця відповідь не те саме, що "умовна компіляція"; IsVisible=Falseозначає, що створені об'єкти подання (хоча немає виклику макета). Це має певну вартість, хоча часто незначну - тому для деяких цілей це нормально. Це не корисно для цього конкретного питання , яке стосується альтернативних стилів - IsVisible тут не корисний.
— ToolmakerSteve

До речі, якщо ви базували свій код на прикладі, який ви бачили десь ще, ви повинні надати посилання для зарахування автора, код якого допоміг вам це створити. Схоже, тут є складність, щоб дизайнер VS міг побачити ці зміни, про що вже згадувалося тут ; якщо це є причиною складності, то вам слід це згадати.
— ToolmakerSteve
Використовуючи наш веб-сайт, ви визнаєте, що прочитали та зрозуміли наші Політику щодо файлів cookie та Політику конфіденційності.
Licensed under cc by-sa 3.0 with attribution required.