web-dev-qa-db-ja.com

XAMLでのカラーコンバーターへのブール値の使用

WPFアプリケーションで作業しています。テキストブロックをボタンにバインドしました。関連するボタンのisEnabledがtrueの場合、テキストブロックの前景を黒色に設定します。コンバーターを使用してこれを実行したいと思います。 しかし、機能していません。また、エラーも発生しません。 「Models」フォルダで以下のクラスを宣言しました。

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

ボタンのenable、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"/>
30
deathrace

return new SolidColorBrush(Colors.Black);を使用します。

41
user1101511

上記の答えは、コンバーターを正しく使用する方法を示しています。ただし、本当にコンバータを使用する必要がありますか?これは、Triggersを使用するXAMLでのみ実行できます。

[〜#〜] 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>

上記の例では、最初のTextBlockIsEnabledを使用してその親のDataTriggerプロパティにバインドし、Foregroundがtrueの場合はある色に設定します。

ただし、これはやりすぎです。IsEnabledプロパティはWPFによって自動的に子に伝達されます。つまり、IsEnabledButtonでfalseに設定すると、TextBlockIsEnabledプロパティが自動的にfalseに更新されます。これは、プロパティTextBlockを使用して自身のTriggerプロパティをtrueの値に対してチェックする2番目のIsEnabledで示されています(そのIsEnabledプロパティは親と同じ)。これは推奨されるアプローチです。

お役に立てれば!

16
F Ruffell

このコンバーターを一般的にするには、ConverterParameterを使用して、valueがtrueまたはfalseのときに挿入される色を指定できます。また、不透明度も重要です。ここでは、パラメーター[ColorNameIfTrue; ColorNameIfFalse; OpacityNumber]を取るコンバーターを提供します。

@ user1101511で言及されているSolidColorBrush()メソッドは_System.Windows.Media_ライブラリの一部であるため、同じライブラリのColorタイプを使用します。この型には、_System.Drawing.Color_クラスのようなColor.FromName()メソッドがありません。

そのため、ColorFromName(string name)というヘルパーメソッドを作成しました。 ConverterParameterの解釈が失敗した場合の代替色として_"LimeGreen"_を指定します。私の場合、valueがfalseの場合、出力を_"Transparent"_にする必要があります。

_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}"
_
7