committed by
GitHub
11 changed files with 338 additions and 49 deletions
@ -0,0 +1,49 @@ |
|||||
|
using System; |
||||
|
using System.Globalization; |
||||
|
|
||||
|
namespace Avalonia.Data.Converters |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// A value converter which calls <see cref="string.Format(string, object)"/>
|
||||
|
/// </summary>
|
||||
|
public class StringFormatValueConverter : IValueConverter |
||||
|
{ |
||||
|
/// <summary>
|
||||
|
/// Initializes a new instance of the <see cref="StringFormatValueConverter"/> class.
|
||||
|
/// </summary>
|
||||
|
/// <param name="format">The format string.</param>
|
||||
|
/// <param name="inner">
|
||||
|
/// An optional inner converter to be called before the format takes place.
|
||||
|
/// </param>
|
||||
|
public StringFormatValueConverter(string format, IValueConverter inner) |
||||
|
{ |
||||
|
Contract.Requires<ArgumentNullException>(format != null); |
||||
|
|
||||
|
Format = format; |
||||
|
Inner = inner; |
||||
|
} |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets an inner value converter which will be called before the string format takes place.
|
||||
|
/// </summary>
|
||||
|
public IValueConverter Inner { get; } |
||||
|
|
||||
|
/// <summary>
|
||||
|
/// Gets the format string.
|
||||
|
/// </summary>
|
||||
|
public string Format { get; } |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public object Convert(object value, Type targetType, object parameter, CultureInfo culture) |
||||
|
{ |
||||
|
value = Inner?.Convert(value, targetType, parameter, culture) ?? value; |
||||
|
return string.Format(culture, Format, value); |
||||
|
} |
||||
|
|
||||
|
/// <inheritdoc/>
|
||||
|
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture) |
||||
|
{ |
||||
|
throw new NotSupportedException("Two way bindings are not supported with a string format"); |
||||
|
} |
||||
|
} |
||||
|
} |
||||
@ -0,0 +1,146 @@ |
|||||
|
// Copyright (c) The Avalonia Project. All rights reserved.
|
||||
|
// Licensed under the MIT license. See licence.md file in the project root for full license information.
|
||||
|
|
||||
|
using System; |
||||
|
using Avalonia.Controls; |
||||
|
using Avalonia.Data; |
||||
|
using Avalonia.Data.Converters; |
||||
|
using Avalonia.Data.Core; |
||||
|
using Xunit; |
||||
|
|
||||
|
namespace Avalonia.Markup.UnitTests.Data |
||||
|
{ |
||||
|
public class BindingTests_Converters |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void Converter_Should_Be_Used() |
||||
|
{ |
||||
|
var textBlock = new TextBlock |
||||
|
{ |
||||
|
DataContext = new Class1(), |
||||
|
}; |
||||
|
|
||||
|
var target = new Binding(nameof(Class1.Foo)) |
||||
|
{ |
||||
|
Converter = StringConverters.NullOrEmpty, |
||||
|
}; |
||||
|
|
||||
|
var expressionObserver = (BindingExpression)target.Initiate( |
||||
|
textBlock, |
||||
|
TextBlock.TextProperty).Observable; |
||||
|
|
||||
|
Assert.Same(StringConverters.NullOrEmpty, expressionObserver.Converter); |
||||
|
} |
||||
|
|
||||
|
public class When_Binding_To_String |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void StringFormatConverter_Should_Be_Used_When_Binding_Has_StringFormat() |
||||
|
{ |
||||
|
var textBlock = new TextBlock |
||||
|
{ |
||||
|
DataContext = new Class1(), |
||||
|
}; |
||||
|
|
||||
|
var target = new Binding(nameof(Class1.Foo)) |
||||
|
{ |
||||
|
StringFormat = "Hello {0}", |
||||
|
}; |
||||
|
|
||||
|
var expressionObserver = (BindingExpression)target.Initiate( |
||||
|
textBlock, |
||||
|
TextBlock.TextProperty).Observable; |
||||
|
|
||||
|
Assert.IsType<StringFormatValueConverter>(expressionObserver.Converter); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class When_Binding_To_Object |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void StringFormatConverter_Should_Be_Used_When_Binding_Has_StringFormat() |
||||
|
{ |
||||
|
var textBlock = new TextBlock |
||||
|
{ |
||||
|
DataContext = new Class1(), |
||||
|
}; |
||||
|
|
||||
|
var target = new Binding(nameof(Class1.Foo)) |
||||
|
{ |
||||
|
StringFormat = "Hello {0}", |
||||
|
}; |
||||
|
|
||||
|
var expressionObserver = (BindingExpression)target.Initiate( |
||||
|
textBlock, |
||||
|
TextBlock.TagProperty).Observable; |
||||
|
|
||||
|
Assert.IsType<StringFormatValueConverter>(expressionObserver.Converter); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
public class When_Binding_To_Non_String_Or_Object |
||||
|
{ |
||||
|
[Fact] |
||||
|
public void StringFormatConverter_Should_Not_Be_Used_When_Binding_Has_StringFormat() |
||||
|
{ |
||||
|
var textBlock = new TextBlock |
||||
|
{ |
||||
|
DataContext = new Class1(), |
||||
|
}; |
||||
|
|
||||
|
var target = new Binding(nameof(Class1.Foo)) |
||||
|
{ |
||||
|
StringFormat = "Hello {0}", |
||||
|
}; |
||||
|
|
||||
|
var expressionObserver = (BindingExpression)target.Initiate( |
||||
|
textBlock, |
||||
|
TextBlock.MarginProperty).Observable; |
||||
|
|
||||
|
Assert.Same(DefaultValueConverter.Instance, expressionObserver.Converter); |
||||
|
} |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void StringFormat_Should_Be_Applied() |
||||
|
{ |
||||
|
var textBlock = new TextBlock |
||||
|
{ |
||||
|
DataContext = new Class1(), |
||||
|
}; |
||||
|
|
||||
|
var target = new Binding(nameof(Class1.Foo)) |
||||
|
{ |
||||
|
StringFormat = "Hello {0}", |
||||
|
}; |
||||
|
|
||||
|
textBlock.Bind(TextBlock.TextProperty, target); |
||||
|
|
||||
|
Assert.Equal("Hello foo", textBlock.Text); |
||||
|
} |
||||
|
|
||||
|
[Fact] |
||||
|
public void StringFormat_Should_Be_Applied_After_Converter() |
||||
|
{ |
||||
|
var textBlock = new TextBlock |
||||
|
{ |
||||
|
DataContext = new Class1(), |
||||
|
}; |
||||
|
|
||||
|
var target = new Binding(nameof(Class1.Foo)) |
||||
|
{ |
||||
|
Converter = StringConverters.NotNullOrEmpty, |
||||
|
StringFormat = "Hello {0}", |
||||
|
}; |
||||
|
|
||||
|
textBlock.Bind(TextBlock.TextProperty, target); |
||||
|
|
||||
|
Assert.Equal("Hello True", textBlock.Text); |
||||
|
} |
||||
|
|
||||
|
private class Class1 |
||||
|
{ |
||||
|
public string Foo { get; set; } = "foo"; |
||||
|
} |
||||
|
} |
||||
|
} |
||||
Loading…
Reference in new issue