ブール値に応じて、表示/非表示にするコントロールがあります。
NegatedBooleanConverterがあり(trueからfalseに、またはその逆に切り替えます)、このコンバーターを最初に実行する必要があります。 BooleanToVisibilityConverterがあり、NegatedBoolConverterの後にこのコンバーターを実行する必要があります。
この問題を解決するにはどうすればよいですか? XAMLでこれを実行したいと思います。
編集: これは可能な解決策です。
それはうまくいかないようです。最初に別のコンバーターで値を変換し、次に変換された値で何かを行います。
私が必要なのは:
私自身の質問にもう一度答えます:私はこのソリューションを何年も使用しています: http://www.codeproject.com/Articles/15061/Piping-Value-Converters-in-WPF
最初のコンバーターを最初に呼び出し、次に2番目のコンバーターを呼び出すなど、2つの既存のコンバーターの新しいコンバーターを作成します。
私はこの解決策にかなり満足しています。
これは私がやったことです:
public class CombiningConverter : IValueConverter
{
public IValueConverter Converter1 { get; set; }
public IValueConverter Converter2 { get; set; }
#region IValueConverter Members
public object Convert(object value, Type targetType, object parameter, System.Globalization.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, System.Globalization.CultureInfo culture)
{
throw new NotImplementedException();
}
#endregion
}
そして私はそれをこのように呼びます:
<converters:CombiningConverter x:Key="negatedBoolToVisibilityConverter" Converter1="{StaticResource NegatedBooleanConverter}" Converter2="{StaticResource BoolToVisibilityConverter}" />
MultiValueConverterも可能だと思います。多分後で試してみるよ。
ナトリウムの素晴らしい答えを拡張しています...
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> { }
この場合、コンバータチェーンは必要ありません。構成可能なコンバーターが必要なだけです。これは上記のCarloの回答に似ていますが、true値とfalse値を明示的に定義します(つまり、非表示、表示、または折りたたみの変換に同じコンバーターを使用できます)。
[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" />
プロジェクトで行うことは、通常のBooleanToVisibilityConverterを作成することです。コンバーターは1つのパラメーター(何でも、文字列、int、boolなど)を取ります。パラメータが設定されている場合は結果を反転し、設定されていない場合は通常の結果を出力します。
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
}
ここでは、2つの個別のコンバーターの代わりにマルチコンバーターを使用することをお勧めします。既存のコンバーターからロジックを再利用できるはずです。まずは このディスカッション をチェックしてください。
私は、ReversedBooleanToVisibilityConverterと呼ばれるものを作成し、基本的にこれら2つがあなたのために行うことを1つのステップで実行しました。
この特定の問題に対処するには、2つのコンバーターを使用する代わりに、ConverterParameterを(ブール値として)使用して独自のBoolToVisibilityConverterを記述し、元のブール値を無効にするかどうかを決定します。
個人的には、完全な変換を行う単一のコンバーターを1つだけ作成します。他の場所で(否定などの)コンバーターを必死に必要としない限り、変換が1か所で1か所で行われると(imo)を維持するのが簡単になります。