Verfügt XAML über eine bedingte Compiler-Direktive für den Debug-Modus?

75

Ich brauche so etwas für Stile in 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>
Ehsan Zargar Ershadi
quelle
2
Was versuchst du zu erreichen?
Tsells
2
Ich brauche verschiedene Stile im Debug-Modus, damit ich im Debug-Modus eine leichtere Ausführung machen kann.
Ehsan Zargar Ershadi

Antworten:

123

Ich musste dies kürzlich tun und war überrascht, wie einfach es war, wenn ich keine eindeutigen Beispiele finden konnte. Ich habe AssemblyInfo.cs Folgendes hinzugefügt:

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

Verwenden Sie dann das AlternateContent-Tag des Markup-kompatiblen Namespace, um Ihren Inhalt basierend auf der Präsenz dieser Namespace-Definition auszuwählen:

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

Wenn nun DEBUG definiert ist, wird auch der "Debug-Modus" definiert, und der Namespace "d" ist vorhanden. Dadurch wählt das AlternateContent-Tag den ersten Codeblock aus. Wenn DEBUG nicht definiert ist, wird der Fallback-Codeblock verwendet.

Dieser Beispielcode wurde nicht getestet, aber es ist im Grunde dasselbe, was ich in meinem aktuellen Projekt verwende, um einige Debug-Schaltflächen bedingt anzuzeigen.

Ich habe einen Blog-Beitrag mit einem Beispielcode gesehen, der sich auf das "Ignorable" -Tag stützte, aber das schien viel weniger klar und einfach zu verwenden als diese Methode.

bj0
quelle
5
Das VS-
Fehlerfenster
1
Meine Lösung kann nicht kompiliert werden, wenn ich den Code zu AssemblyInfo.cs hinzufüge. Ich verstehe The type or namespace name 'XmlnsDefinitionAttribute' could not be found (are you missing a using directive or an assembly reference?). Was kann ich tun?
Nimbudew
1
XmlnsDefinitionAttributeist im System.Windows.MarkupNamespace. Dieser Namespace befindet sich in der System.Xaml.dllAssembly, die meiner Meinung nach automatisch hinzugefügt wird, wenn Sie ein WPF-Projekt in Visual Studio erstellen.
bj0
1
Wenn Sie eine Funktion zwischen AlternateContent verwenden, die der IComponentConnector.Connect-Methode Code hinzufügt (Ereignishandler wie OnClick do), werden die connectionIds vollständig ausgelastet und InitializeComponent schlägt entweder zur Laufzeit fehl oder führt unerwartete Dinge aus (Verwechseln von Ereignishandlern).
springy76
5
Beachten Sie, dass Sie möglicherweise "mc" Ignorable gegen sich selbst markieren müssen, dh mc: Ignorable = "d mc"
JulieC
2

Sie können eine Vorlagenauswahl verwenden. Die DataTemplateSelector-Klasse ist etwas, das Sie codieren. Mit der von Ihnen überschriebenen Vorlagenauswahlmethode können Sie Ihre Präprozessoranweisungen einfügen.

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

Josh C.
quelle
A DataTemplateSelectorkönnte relevant sein, wenn es um alternative Ansichtsinhalte ging , aber um alternative Stile - es gibt keinen "Selektor" für alternative Stile. Nun, Sie könnten zwei separate Kopien des Inhalts mit unterschiedlichen Stilen erstellen ... aber das klingt nicht nach dem, was Sie hier sagen wollen.
ToolmakerSteve
2

Dies ist in WPF / Silverlight / WP7 nicht möglich.

Interessanterweise beschreibt das Normdokument ISO / IEC 29500 , wie dies in einem XML-Dokument behandelt werden soll, und XAML unterstützt eines der Elemente aus dieser Spezifikation, mit mc:Ignorabledenen wir Folgendes tun können:

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

Attribute auskommentieren. Ich denke, es wäre cool, wenn XAML eines Tages den Rest der Spezifikation unterstützen würde, die das Laden alternativer Inhalte ermöglicht.

Das mc:IgnorableAttribut wird von Blend verwendet, um die Entwurfszeitfunktionalität zu unterstützen.

JasonRShaver
quelle
1
Was hat die Spezifikation des MS OFfice Open XML-Dateiformats mit XAML zu tun?
Nicholas Carey
Panzer, aber dieses Problem passt nicht zu meiner Situation.
Ehsan Zargar Ershadi
Nicholas, das XAML-Parser-Team (SL4, WP7.1, WPF) hat sich dafür entschieden, diese Spezifikation zu verwenden, um ihre Anforderungen zum Ignorieren von Attributen zu lösen, anstatt nur etwas zu erfinden. Aus diesem Grund ist für einige der Standard-XAML-Seiten der Namespace 'mc' definiert.
JasonRShaver
1

Ich bin der Meinung, dass die gegebenen Antworten nicht am einfachsten zu verwenden sind. Hier ist meine Lösung mit einer benutzerdefinierten anhängbaren Abhängigkeitseigenschaft:

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);
        }
    }
}

und das xaml würde so verwendet werden:

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

Ich habe es als Bool behalten, falls Sie dort eine andere Sichtbarkeitslogik hinzufügen möchten. Dies ist ein schöner einfacher Schalter, der an jedes Steuerelement gebunden und an dieses angehängt werden kann

Dallin Beuller
quelle
Gute Idee, aber die Implementierung kann viel einfacher sein. Debug / Release ändert sich offensichtlich nicht während eines Laufs, sodass Sie nicht das gesamte Binding / Dependency-Material benötigen. Alles, was Sie brauchen, ist eine statische Variable "Debug" in Util, die beim Debuggen "True" und beim Nicht-Debug "False" ist. (Und der Einfachheit halber ein zweites statisches "Release", das beim Debuggen falsch ist.) Dann tun Sie es <Label IsVisible={Static Util:Debug}.
ToolmakerSteve
1
HINWEIS: Diese Antwort ist nicht mit "bedingte Kompilierung" identisch. IsVisible=Falsebedeutet, dass die Ansichtsobjekte erstellt werden (obwohl kein Layoutaufruf erfolgt). Dies hat einige Kosten, wenn auch oft nur geringe - ist also für einige Zwecke in Ordnung. Es ist nicht nützlich für diese spezielle Frage , bei der es um alternative Stile geht - IsVisible ist dort nicht hilfreich.
ToolmakerSteve
Übrigens, wenn Sie Ihren Code auf ein Beispiel gestützt haben, das Sie woanders gesehen haben, sollten Sie einen Link bereitstellen, um den Autor anzurechnen, dessen Code Ihnen bei der Erstellung geholfen hat. Es sieht so aus, als ob die Komplexität vorhanden ist, damit der VS-Designer diese Änderung sehen kann, wie hier erwähnt . Wenn dies der Grund für die Komplexität ist, sollten Sie dies erwähnen.
ToolmakerSteve