54

ブール値に応じて、表示/非表示にしたいコントロールがあります。

NegatedBooleanConverter(true から false に、またはその逆に切り替える) があり、最初にこのコンバーターを実行する必要があります。があり、BooleanToVisibilityConverterの後にこのコンバーターを実行する必要がありNegatedBoolConverterます。

この問題を解決するにはどうすればよいですか? これを XAML で実行したいと考えています。

編集:これは可能な解決策です。

それはうまくいかないようです。最初に個別のコンバーターで値を変換し、次に変換された値で何かを行います。

私が必要とするのは:

  • 最初のコンバーターで値を変換します (これにより、convertedValue が得られます)。
  • 2番目のコンバーターでconvertedValueを変換します。必要なのはこの結果です。
4

11 に答える 11

69

これは私がしたことです:

public class CombiningConverter : IValueConverter
{
    public IValueConverter Converter1 { get; set; }
    public IValueConverter Converter2 { get; set; }

    public object Convert(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        object convertedValue =
            Converter1.Convert(value, targetType, parameter, culture);
        return Converter2.Convert(
            convertedValue, targetType, parameter, culture);
    }

    public object ConvertBack(
        object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

そして私はそれを次のように呼びます:

<converters:CombiningConverter
    x:Key="negatedBoolToVisibilityConverter"
    Converter1="{StaticResource NegatedBooleanConverter}"
    Converter2="{StaticResource BoolToVisibilityConverter}" />

AMultiValueConverterもあり得ると思います。多分私は後でそれを試してみます。

于 2009-10-20T14:28:14.887 に答える
34

ナトリウムの素晴らしい答えを拡張します...

XAML

<conv:ConverterChain x:Key="convBoolToInverseToVisibility">
    <conv:BoolToInverseConverter />
    <BooleanToVisibilityConverter />
</conv:ConverterChain>

クラス

/// <summary>Represents a chain of <see cref="IValueConverter"/>s to be executed in succession.</summary>
[ContentProperty("Converters")]
[ContentWrapper(typeof(ValueConverterCollection))]
public class ConverterChain : IValueConverter
{
    private readonly ValueConverterCollection _converters= new ValueConverterCollection();

    /// <summary>Gets the converters to execute.</summary>
    public ValueConverterCollection Converters
    {
        get { return _converters; }
    }

    #region IValueConverter Members

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Converters
            .Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return Converters
            .Reverse()
            .Aggregate(value, (current, converter) => converter.Convert(current, targetType, parameter, culture));
    }

    #endregion
}

/// <summary>Represents a collection of <see cref="IValueConverter"/>s.</summary>
public sealed class ValueConverterCollection : Collection<IValueConverter> { }
于 2011-12-05T22:09:11.143 に答える
8

この場合、コンバーター チェーンは必要ありません。構成可能なコンバーターが必要なだけです。これは上記のカルロの回答に似ていますが、真と偽の値を明示的に定義しています (つまり、変換に同じコンバーターを使用できることを意味しますHidden) 。VisibleCollapsed

[ValueConversion(typeof(bool), typeof(Visibility))]
public class BoolToVisibilityConverter : IValueConverter
{
    public Visibility TrueValue { get; set; }
    public Visibility FalseValue { get; set; }

    public BoolToVisibilityConverter()
    {
        // set defaults
        FalseValue = Visibility.Hidden;
        TrueValue = Visibility.Visible;
    }

    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        return (bool)value ? TrueValue : FalseValue;
    }

    public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
    {
        throw new NotImplementedException();
    }
}

次に、XAML で:

<BoolToVisibilityConverter x:Key="BoolToVisibleConverter"
                           FalseValue="Hidden"
                           TrueValue="Visible" />
于 2015-02-04T08:43:18.793 に答える
4

What we do in our project is make a regular BooleanToVisibilityConverter, said converter takes one parameter (anything at all, a string, an int, bool, whatever). If the parameter is set it inverts the result, if not, it spits out the regular result.

public class BooleanToVisibilityConverter : IValueConverter
{
    #region IValueConverter Members

    public object Convert(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        bool? isVisible = value as bool?;
        if (parameter != null && isVisible.HasValue)
            isVisible = !isVisible;
        if (isVisible.HasValue && isVisible.Value == true)
            return Visibility.Visible;
        else
            return Visibility.Collapsed;
    }

    public object ConvertBack(object value, System.Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        throw new System.NotImplementedException();
    }

    #endregion
}
于 2009-10-20T14:21:56.293 に答える
3

私自身の質問にもう一度答えるには:私はこのソリューションを何年も使用しています:

WPF のパイプ値コンバーター - CodeProject

2 つの既存のコンバーターから新しいコンバーターを作成し、最初のコンバーターを最初に呼び出し、次に 2 つ目のコンバーターなどを呼び出します。

このソリューションにはかなり満足しています。

于 2016-08-24T05:54:21.563 に答える
0

ReversedBooleanToVisibilityConverter基本的にこれら 2 つが行うことを 1 つのステップで実行するために呼び出したものを作成しました。

于 2009-10-20T13:43:16.653 に答える
0

この特定の問題に対処するには、2 つのコンバーターを使用する代わりに、 (として) をBoolToVisibilityConverter使用して元のブール値を否定するかどうかを決定する独自のコンバーターを作成できます。ConverterParameterbool

于 2009-10-20T13:47:31.817 に答える
0

個人的には、完全な変換を行う単一のコンバーターを 1 つだけ作成します。他の場所でコンバーター (否定など) がどうしても必要でない限り、変換が 1 か所で一度行われると、保守が容易になります (imo)。

于 2009-10-20T13:48:19.473 に答える
0

ここでは、2 つの別個のコンバーターではなく、マルチコンバーターを使用することをお勧めします。既存のコンバーターのロジックを再利用できるはずです。開始するには、このディスカッションを確認してください。

于 2009-10-20T14:16:21.320 に答える