Делает XAML, имеют условные директивы компилятора в режиме отладки?


Мне нужно что-то вроде этого для стилей в 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>
4 52

4 ответа:

Я недавно должен был сделать это и был удивлен тем, как просто это было, когда я не мог легко найти какие-либо четкие примеры. То, что я сделал, это добавить следующее В AssemblyInfo.cs:

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

затем используйте тег AlternateContent пространства имен markup-compatability, чтобы выбрать содержимое на основе наличия этого определения пространства имен:

<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 определен," debug-mode "также будет определен, и пространство имен" d " будет присутствовать. Это делает Тег AlternateContent выберите первый блок кода. Если DEBUG не определен, будет использоваться резервный блок кода.

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

Я видел сообщение в блоге с некоторым примером кода, который полагался на тег "Ignorable", но это казалось намного менее понятным и простым в использовании в качестве этого метода.

вы можете использовать селектор шаблонов. Класс DataTemplateSelector-это то, что вы кодируете. С помощью метода выбора шаблона, который вы переопределяете, вы можете поместить свои директивы препроцессора.

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

Это невозможно в 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 однажды поддержал остальную часть спецификации, которая позволяет загружать альтернативный контент.

The mc:Ignorable атрибут используется Blend для поддержки функциональности времени разработки.

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

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>

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