Логический параметр CommandParameter в XAML
У меня есть этот код (который работает в самый раз):
<KeyBinding Key="Enter" Command="{Binding ReturnResultCommand}">
<KeyBinding.CommandParameter>
<s:Boolean>
True
</s:Boolean>
</KeyBinding.CommandParameter>
</KeyBinding>
Где "s", конечно, пространство имен System.
Но эта команда вызывается довольно много раз, и в действительности она надувает довольно простой код XAML. Действительно ли это самое короткое обозначение параметра логической команды в XAML (кроме разделения команды на несколько команд)?
5 ответов
Я как-то склонен не читать вопросы... Во всяком случае, это может быть немного взломать, но вы можете извлечь из KeyBinding
учебный класс:
public class BoolKeyBinding : KeyBinding
{
public bool Parameter
{
get { return (bool)CommandParameter; }
set { CommandParameter = value; }
}
}
Использование:
<local:BoolKeyBinding ... Parameter="True"/>
И еще одно не очень странное решение:
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>
Использование:
<KeyBinding ... CommandParameter="{StaticResource True}"/>
Проще всего определить следующее в Ресурсах
<System:Boolean x:Key="FalseValue">False</System:Boolean>
<System:Boolean x:Key="TrueValue">True</System:Boolean>
и используйте это как:
<Button CommandParameter="{StaticResource FalseValue}"/>
Или, может быть, это:
<Button.CommandParameter>
<s:Boolean>True</s:Boolean>
</Button.CommandParameter>
Где s это пространство имен:
xmlns:s="clr-namespace:System;assembly=mscorlib"
Я только что нашел еще более общее решение с этим расширением разметки:
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;
}
}
Использование ("wpf:" - это пространство имен, в котором находится расширение):
<KeyBinding Key="F8" Command="{Binding SomeCommand}" CommandParameter="{wpf:SystemType Bool=True}"/>
Вы даже получаете варианты True
а также False
после ввода Bool=
и типа безопасность!
Возможно что-то вроде
<KeyBinding Key="Enter" Command="{Binding ReturnResultCommand}"
CommandParameter="{x:Static StaticBoolean.True}" />
где StaticBoolean
является
public static class StaticBoolean
{
public static bool True
{
get { return true; }
}
}
Вот еще один подход, где вы определяете свои собственные расширения разметки, которые возвращают True
или же False
(или любое другое значение, которое вы хотите). Затем вы просто используете их прямо в XAML, как и любое другое расширение разметки:
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;
}
Затем вы используете их так (при условии, что ваше импортированное пространство имен 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}}">
Я на самом деле определяю много пользовательских MarkupExtension
классы для многих общих вещей, которые я не хочу хранить в своих ресурсах.