Boolescher CommandParameter in XAML


76

Ich habe diesen Code (der genau richtig funktioniert):

<KeyBinding Key="Enter" Command="{Binding ReturnResultCommand}">
    <KeyBinding.CommandParameter>
        <s:Boolean>
            True
        </s:Boolean>
    </KeyBinding.CommandParameter>
</KeyBinding>

Wobei "s" natürlich der System-Namespace ist.

Dieser Befehl wird jedoch einige Male aufgerufen und bläst den ansonsten recht einfachen XAML-Code wirklich auf. Ist dies wirklich die kürzeste Notation des booleschen Befehlsparameters in XAML (abgesehen von der Aufteilung des Befehls in mehrere Befehle)?

Antworten:


108

Dies mag ein bisschen hacken, aber Sie können von der KeyBindingKlasse ableiten :

public class BoolKeyBinding : KeyBinding
{
    public bool Parameter
    {
        get { return (bool)CommandParameter; }
        set { CommandParameter = value; }
    }
}

Verwendung:

<local:BoolKeyBinding ... Parameter="True"/>

Und noch eine nicht so seltsame Lösung:

xmlns:s="clr-namespace:System;assembly=mscorlib"
<Application.Resources>
    <!-- ... -->
    <s:Boolean x:Key="True">True</s:Boolean>
    <s:Boolean x:Key="False">False</s:Boolean>
</Application.Resources>

Verwendung:

<KeyBinding ... CommandParameter="{StaticResource True}"/>

Dies gilt nicht nur für Tastenkombinationen, sondern auch für Schaltflächen und dergleichen.
— Matěj Zábský

Was ist dann mit meiner zweiten Methode, die ich gerade hinzugefügt habe?
— HB

1
Interessante Idee, die mir nicht eingefallen ist. Ich werde es versuchen.
— Matěj Zábský

@HB Warum gibt meins immer false zurück? Ich kann das nicht zum Laufen bringen.
— Igor

2
@HB Schöne Antwort, vielleicht könnten Sie dies hinzufügen: xmlns:s="clr-namespace:System;assembly=mscorlib"zu Ihrer Antwort :)
— BendEg

63

Am einfachsten ist es, Folgendes in den Ressourcen zu definieren

<System:Boolean x:Key="FalseValue">False</System:Boolean>
<System:Boolean x:Key="TrueValue">True</System:Boolean>

und benutze es wie:

<Button CommandParameter="{StaticResource FalseValue}"/>

4
und Sie müssen hinzufügen: xmlns:System="clr-namespace:System;assembly=mscorlib"zur Benutzersteuerung
— Alex

26

Oder vielleicht das:

<Button.CommandParameter>
    <s:Boolean>True</s:Boolean>
</Button.CommandParameter>

Wo s ist der Namespace:

 xmlns:s="clr-namespace:System;assembly=mscorlib"

24

Ich habe gerade eine noch allgemeinere Lösung mit dieser Markup-Erweiterung gefunden:

public class SystemTypeExtension : MarkupExtension
{
    private object parameter;

    public int Int{set { parameter = value; }}
    public double Double { set { parameter = value; } }
    public float Float { set { parameter = value; } }
    public bool Bool { set { parameter = value; } }
    // add more as needed here

    public override object ProvideValue(IServiceProvider serviceProvider)
    {
        return parameter;
    }
}

Verwendung ("wpf:" ist der Namespace, in dem sich die Erweiterung befindet):

<KeyBinding Key="F8" Command="{Binding SomeCommand}" CommandParameter="{wpf:SystemType Bool=True}"/>

Sie erhalten sogar die Optionen Trueund Falsenach dem Tippen Bool=und Tippen Sicherheit!


@ marbel82 Soweit ich weiß, können Sie die "Erweiterung" genauso wie "Attribut" für Attribute weglassen. Probieren Sie es aus! Aber das Hinzufügen einer Erweiterung wird natürlich nicht schaden.
— Onur

Onur du hast recht! Das wusste ich nicht. Sie sollten diese Informationen in die Antwort schreiben. Zuvor habe ich Ihren Code getestet, aber ich hatte woanders einen Fehler.
— Marbel82

1
Das ist so schlau, dass es krank ist. Vielen Dank für Ihre Lösung.
— John Sully

1
Erstellen Sie einfach eine Markup-Erweiterung pro Typ (z. B. BooleanExtension) und Sie können z. B. CommandParameter={x:Boolean True}ähnlich wie docs.microsoft.com/en-us/dotnet/framework/xaml-services/…
— Wouter

6

Vielleicht so etwas wie

<KeyBinding Key="Enter" Command="{Binding ReturnResultCommand}"
    CommandParameter="{x:Static StaticBoolean.True}" />

wo StaticBooleanist

public static class StaticBoolean
{
    public static bool True
    {
        get { return true; }
    }
}

Ja. Der Wert wird als Zeichenfolge an den Befehl übergeben (was auch nicht das ist, was ich will).
— Matěj Zábský

Hmm, wie würde ich den Konverter in diesem Zusammenhang verwenden?
— Matěj Zábský

Sorry fand etwas einfacher.
— Bala R

1
Das war eine interessante Entwicklung, muss ich sagen, habe alle Schritte gesehen: P Jetzt liegt es an einer Bool-Ressource (die Sie auch in Xaml machen können, wie in meiner Antwort)
— HB

Ihre Lösung gefällt mir sehr gut. Ich schlage eine kleine Verbesserung vor. Anstatt geteinfach eine Konstante zu initialisieren public static bool True = true;und eine weitere Konstante hinzuzufügen public static bool False = false;.
— Marbel82

1

Hier ist ein weiterer Ansatz, bei dem Sie Ihre eigenen Markup-Erweiterungen definieren, die Trueoder False(oder einen anderen gewünschten Wert) zurückgeben. Dann verwenden Sie sie einfach direkt in XAML wie jede andere Markup-Erweiterung:

public class TrueExtension : MarkupExtension {
    public override object ProvideValue(IServiceProvider serviceProvider) => true;
}

public class FalseExtension : MarkupExtension {
    public override object ProvideValue(IServiceProvider serviceProvider) => false;
}

public class DoubleExtension : MarkupExtension {
    public DoubleExtension(){};
    public DoubleExtension(double value) => Value = value;
    public double Value { get; set; }
    public override object ProvideValue(IServiceProvider serviceProvider) => Value;
}

Sie verwenden sie dann folgendermaßen (vorausgesetzt, Ihr importierter Namespace ist mx):

<KeyBinding Key="Enter"
    Command="{Binding ReturnResultCommand}"
    CommandParameter="{mx:True}" />

<Button Visibility="{Binding SomeProperty,
    Converter={SomeBoolConverter},
    ConverterParameter={mx:True}}">

<!-- This guarantees the value passed is a double equal to 42.5 -->
<Button Visibility="{Binding SomeProperty,
    Converter={SomeDoubleConverter},
    ConverterParameter={mx:Double 42.5}}">

Ich definiere tatsächlich viele benutzerdefinierte MarkupExtensionKlassen für viele allgemeine Dinge, die ich nicht unbedingt in meinen Ressourcen speichern möchte.

Durch die Nutzung unserer Website bestätigen Sie, dass Sie unsere Cookie-Richtlinie und Datenschutzrichtlinie gelesen und verstanden haben.
Licensed under cc by-sa 3.0 with attribution required.