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 2012年

2
我需要在调试模式下使用不同的样式,以便在调试模式下可以更轻松地执行代码。
Ehsan Zargar Ershadi'1

Answers:


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,将使用后备代码块。

此示例代码未经测试,但与我在当前项目中有条件地显示一些调试按钮所用的基本上相同。

我确实看到了一篇博客文章,其中包含一些示例代码,这些示例代码依赖于“ Ignorable”标签,但这种方法看起来不太清晰且易于使用。


5
VS错误窗格不喜欢这样,尽管一切都按预期进行:链接
springy76

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
XmlnsDefinitionAttributeSystem.Windows.Markup名称空间中。该名称空间在System.Xaml.dll程序集中,我相信在Visual Studio中创建WPF项目时会自动添加该名称空间。
bj0

1
如果在AlternateContent之间使用向IComponentConnector.Connect方法添加代码的功能(如OnClick这样的事件处理程序),则将完全断开connectionId,并且InitializeComponent将在运行时失败或发生意外的事情(混合事件处理程序)。
springy76 '16

5
请注意,您可能需要在自身上标记“ mc”为Ignorable,即mc:Ignorable =“ d mc”
JulieC

2

您可以使用模板选择器。DataTemplateSelector类是您编写的东西。使用您覆盖的模板选择方法,您可以放置​​预处理程序指令。

http://msdn.microsoft.com/zh-CN/library/system.windows.controls.datatemplateselector.aspx


DataTemplateSelector如果问题是关于替代视图内容,则A可能是相关的,但它是关于替代样式的-替代样式没有“选择器”。好了,您可以使用不同的样式创建两个单独的内容副本...但这听起来不像您想要在这里说的那样。
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:IgnorableBlend使用该属性来支持设计时功能。


1
MS OFfice Open XML文件格式规范与XAML有什么关系?
尼古拉斯·凯里

坦克,但这个问题不适合我的情况。
Ehsan Zargar Ershadi'1

Nicholas,XAML分析器团队(SL4,WP7.1,WPF)选择使用该规范来解决他们忽略属性的需求,而不是仅仅弥补一些不足。这就是为什么某些默认XAML页面定义了'mc'名称空间的原因。
JasonRShaver 2012年

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中的静态变量“ Debug”,调试时为True,否则为False。(为方便起见,在调试时,第二个静态“发布”为False。)然后执行<Label IsVisible={Static Util:Debug}
ToolmakerSteve

1
注意:此答案与“条件编译”不同;IsVisible=False表示创建了视图对象(尽管没有布局调用)。这虽然要花很少的钱,但通常要花很少的钱-出于某些目的也可以。它对于这个有关替代样式的特定问题没有帮助-IsVisible在此没有帮助。
ToolmakerSteve

顺便说一句,如果您将代码基于在其他地方看到的示例,则应提供一个链接,以感谢其代码帮助您创建了该代码的作者。就像这里提到的那样,看起来似乎很复杂,VS设计者可以看到这种变化。如果那是造成复杂性的原因,那么您应该提到这一点。
ToolmakerSteve
By using our site, you acknowledge that you have read and understand our Cookie Policy and Privacy Policy.
Licensed under cc by-sa 3.0 with attribution required.