Ответ 1
использование вернуть новый SolidColorBrush (Colors.Black);
Я работаю над приложением WPF. Я привязал свой текстовый блок к своей кнопке. Я хочу установить переднего плана моего текстового блока на черный цвет, когда его связанная кнопка isEnabled - true. Я хочу сделать это с помощью конвертера. Но его не работает. также не давая никаких ошибок. Я объявил следующий класс в моей папке "Модели".
public class BrushColorConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if ((bool)value)
{
{
return System.Windows.Media.Colors.Black;
}
}
return System.Windows.Media.Colors.LightGreen;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
Кнопка включения, isable изменения свойств из viewmodel (например, с помощью RaiseCanExecuteChanged)())
Связанные с текстовым блоком вещи в XAML:
<Window.Resources>
<local:BrushColorConverter x:Key="BConverter"></local:BrushColorConverter>
</Window.Resources>
<Button>(!..all button properties..!)</Button>
<TextBlock x:Name="AnswerText"
Text="Answer"
Foreground="{Binding ElementName=AnswerButton,Path=IsEnabled, Converter={StaticResource BConverter}}"
TextWrapping="Wrap"/>
использование вернуть новый SolidColorBrush (Colors.Black);
Ответ выше показывает, как правильно использовать конвертер. Однако вам действительно нужно использовать конвертер? Это можно сделать в XAML только с помощью Triggers
:
XAML
<StackPanel>
<Button IsEnabled="{Binding ElementName=isEnabledCheckBox, Path=IsChecked}">
<TextBlock Text="Answer" TextWrapping="Wrap">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type Button}}, Path=IsEnabled}" Value="True">
<Setter Property="Foreground" Value="Green"/>
</DataTrigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Button>
<Button IsEnabled="{Binding ElementName=isEnabledCheckBox, Path=IsChecked}">
<TextBlock Text="Answer" TextWrapping="Wrap">
<TextBlock.Style>
<Style TargetType="{x:Type TextBlock}">
<Style.Triggers>
<Trigger Property="IsEnabled" Value="True">
<Setter Property="Foreground" Value="Green"/>
</Trigger>
</Style.Triggers>
</Style>
</TextBlock.Style>
</TextBlock>
</Button>
<CheckBox x:Name="isEnabledCheckBox" Content="Toggle IsEnable on Buttons above" />
</StackPanel>
В приведенном выше примере первый TextBlock
связывается со своим родительским свойством IsEnabled
с помощью DataTrigger
и устанавливает Foreground
в некоторый цвет, если он истинен.
Однако это избыточное - свойство IsEnabled
автоматически распространяется на детей с помощью WPF. То есть, если вы установите для параметра IsEnabled
значение false на Button
, то ваш TextBlock
будет иметь свойство IsEnabled
автоматически обновлено до false. Это показано во втором TextBlock
, который использует свойство Trigger
для проверки собственного свойства IsEnabled
на значение true (поскольку его свойство IsEnabled
будет таким же, как и его родительское). Это был бы предпочтительный подход.
Надеюсь, это поможет!
Чтобы сделать этот общий конвертер, вы можете использовать ConverterParameter
для указания цветов, которые должны быть вставлены, когда value
является истинным или ложным. Также может представлять интерес непрозрачность. Я здесь предоставляю конвертер, который принимает параметр [ColorNameIfTrue; ColorNameIfFalse; OpacityNumber].
Так как метод SolidColorBrush()
, упомянутый @user1101511, является частью библиотеки System.Windows.Media
, он использует тип Color
из той же библиотеки. Этот тип не имеет метода Color.FromName()
, как класс System.Drawing.Color
.
Поэтому я сделал вспомогательный метод под названием ColorFromName(string name)
. Я указываю "LimeGreen"
как резервный цвет, если интерпретация ConverterParameter
не выполняется. В моем случае я хочу, чтобы результат был "Transparent"
, когда value
имеет значение false.
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Media;
namespace MyConverters
{
[ValueConversion(typeof(bool), typeof(SolidColorBrush))]
class BoolToColorBrushConverter : IValueConverter
{
#region Implementation of IValueConverter
/// <summary>
///
/// </summary>
/// <param name="value">Bolean value controlling wether to apply color change</param>
/// <param name="targetType"></param>
/// <param name="parameter">A CSV string on the format [ColorNameIfTrue;ColorNameIfFalse;OpacityNumber] may be provided for customization, default is [LimeGreen;Transperent;1.0].</param>
/// <param name="culture"></param>
/// <returns>A SolidColorBrush in the supplied or default colors depending on the state of value.</returns>
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
SolidColorBrush color;
// Setting default values
var colorIfTrue = Colors.LimeGreen;
var colorIfFalse = Colors.Transparent;
double opacity = 1;
// Parsing converter parameter
if (parameter != null)
{
// Parameter format: [ColorNameIfTrue;ColorNameIfFalse;OpacityNumber]
var parameterstring = parameter.ToString();
if (!string.IsNullOrEmpty(parameterstring))
{
var parameters = parameterstring.Split(';');
var count = parameters.Length;
if (count > 0 && !string.IsNullOrEmpty(parameters[0]))
{
colorIfTrue = ColorFromName(parameters[0]);
}
if (count > 1 && !string.IsNullOrEmpty(parameters[1]))
{
colorIfFalse = ColorFromName(parameters[1]);
}
if (count > 2 && !string.IsNullOrEmpty(parameters[2]))
{
double dblTemp;
if (double.TryParse(parameters[2], NumberStyles.AllowDecimalPoint, CultureInfo.InvariantCulture.NumberFormat, out dblTemp))
opacity = dblTemp;
}
}
}
// Creating Color Brush
if ((bool) value)
{
color = new SolidColorBrush(colorIfTrue);
color.Opacity = opacity;
}
else
{
color = new SolidColorBrush(colorIfFalse);
color.Opacity = opacity;
}
return color;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
public static Color ColorFromName(string colorName)
{
System.Drawing.Color systemColor = System.Drawing.Color.FromName(colorName);
return Color.FromArgb(systemColor.A, systemColor.R, systemColor.G, systemColor.B);
}
}
Из xaml приведенный выше преобразователь можно использовать следующим образом:
Background="{Binding MyBooleanValue, Converter={StaticResource BoolToColorBrushConverter}, ConverterParameter=LimeGreen;Transperent;0.2, Mode=OneWay}"