Имеет ли 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>
Ответы
Ответ 1
Мне недавно пришлось это сделать, и я был удивлен, насколько это было просто, когда я не мог легко найти какие-либо четкие примеры. Я добавил в 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, будет также определен режим debug-mode, и будет присутствовать пространство имен d. Это приводит к тому, что тег AlternateContent выбирает первый блок кода. Если DEBUG не определен, будет использоваться резервный блок кода.
Этот пример кода не был протестирован, но в основном это то же самое, что я использую в своем текущем проекте, чтобы условно показать некоторые кнопки отладки.
Я видел сообщение в блоге с некоторым примером кода, который основывался на теге "Игнорируемый", но это казалось намного менее понятным и простым в использовании в качестве этого метода.
Ответ 2
Вы можете использовать селектор шаблонов. Класс DataTemplateSelector - это код, который вы кодируете. С помощью метода выбора шаблона, который вы переопределите, вы можете разместить директивы препроцессора.
http://msdn.microsoft.com/en-us/library/system.windows.controls.datatemplateselector.aspx
Ответ 3
Это невозможно в 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 для поддержки функциональности времени разработки.
Ответ 4
Я чувствую, что данные ответы не самые простые в использовании. Вот мое решение с использованием настраиваемого свойства зависимой зависимости:
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 на случай, если вы захотите добавить в него другую логику видимости. Это хороший простой переключатель, который может быть привязан к любому элементу управления