这是我想使用多转换器实现的伪代码。
IF vm.AvatarFilePath IS NOT NULL THEN
Image.Source = {Binding AvatarPath}
ELSE
If vm.Gender == {x:Static vm:Gender.Female} THEN
Image.Source = {StaticResource Img_Female}
ELSE
Image.Source = {StaticResource Img_Male}
ENDIF
ENDIF
请注意,我不相信多转换器是正确的方法,我在此处发布了一个类似的问题,试图用 DataTriggers 解决这个问题。
我对 MultiConverter 实现的尝试(如下)有问题:
- 它与 {Dependency.UnsetValue} 一起崩溃,这表明绑定是错误的
- 它可能会或可能不会返回正确的类型 BitmapSource。它需要处理图像的两个源,一个由 Gender 确定,一个基于 Resx 的源,或者一个文件路径。我不知道如何仅通过检查结果来捕获错误的文件路径,因为没有引发错误(我可以做一个 File.Exists 但似乎有点矫枉过正)。
- 为单元测试公开代码这一事实并不像看起来那么有用,因为我不知道有一种简单且便宜的方法来比较图像相等性(请参阅下面的单元测试)。
如何开始清理此转换器代码和绑定?
干杯,
贝里尔
Converter.转换代码
public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture)
{
values.ThrowIfNull("values");
foreach (var value in values) {
if (value != null && value.ToString().Equals("{DependencyProperty.UnsetValue}")) return Binding.DoNothing;
}
values[1].ThrowIfNull("gender (value[1])");
var avatarPath = values[0] as string;
BitmapSource result;
if (string.IsNullOrWhiteSpace(avatarPath)) {
var gender = (Gender) values[1];
object bitmapSource;
switch (gender)
{
case Gender.Female:
bitmapSource = DomainSubjects.Img_Female;
break;
default:
bitmapSource = DomainSubjects.Img_Male;
break;
}
result = BitmapHelper.GetBitmapSource(bitmapSource);
}
else {
var bi = new BitmapImage();
bi.BeginInit();
bi.UriSource = new Uri(avatarPath, UriKind.RelativeOrAbsolute);
bi.EndInit();
result = bi;
}
return result;
}
位图助手代码
public static BitmapSource GetBitmapSource(object source)
{
BitmapSource bitmapSource = null;
if (source is Icon)
{
var icon = source as Icon;
// For icons we must create a new BitmapFrame from the icon data stream
// The approach we use for bitmaps (below) doesn't work when setting the
// Icon property of a window (although it will work for other Icons)
//
using (var iconStream = new MemoryStream())
{
icon.Save(iconStream);
iconStream.Seek(0, SeekOrigin.Begin);
bitmapSource = BitmapFrame.Create(iconStream);
}
}
else if (source is Bitmap)
{
var bitmap = source as Bitmap;
var bitmapHandle = bitmap.GetHbitmap();
bitmapSource = Imaging
.CreateBitmapSourceFromHBitmap(bitmapHandle, IntPtr.Zero, Int32Rect.Empty, BitmapSizeOptions.FromEmptyOptions());
bitmapSource.Freeze();
DeleteObject(bitmapHandle);
}
return bitmapSource;
}
xml绑定
<Image Grid.Column="1" Grid.Row="4"
HorizontalAlignment="Center" Margin="10, 0" Width="96" Height="96" Stretch="UniformToFill"
>
<Image.Source>
<MultiBinding Converter="{StaticResource avatarPathConv}">
<Binding Path="AvatarPath"/>
<Binding Path="Gender"/>
</MultiBinding>
</Image.Source>
</Image>
无用的单元测试(加分!)
[Test]
public void Convert_AvatarPath_IfBadString_DefaultImage() {
var conv = new AvatarPathConverter();
var result = conv.Convert(new object[] {"blah", Gender.Male}, null, null, CultureInfo.InvariantCulture);
Assert.That(result, Is.EqualTo(DomainSubjects.Img_Male));
}