<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label
Width="30"
Height="30" >
<svgc:SvgViewbox IsHitTestVisible="False" Source="/Resources/Logistics/{Binding Code}.svg"/>
</Label>
<Label Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
一个Tab控件,在标题显示一个图标和一个文字, 数据绑定的字段是Name和Code,是一组物流公司的图标和名称,需要用Code指向一个svg图标。
svg用了sharpvectors,我想应该和普通图片一样。现在是{Binding Code}直接写资源地址,可以正常显示,但想每个tab显示自己的实现不了,我尝试利用资源key来访问,用StringFormat来访问,都没有实现。
public string CodeUrl => @"/Resources/Logistics/" + Code + ".svg";
我在视图模型里加了一个属性,是可以正常绑定了
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Label Width="30" Height="30" >
<svgc:SvgViewbox IsHitTestVisible="False" Source="{Binding CodeUrl}"/>
</Label>
<Label Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
<TabControl.ContentTemplate>
但我不想在视图模型里加字段,难道要用类型转换器?
要实现在Tab控件的标题中显示不同的图标,可以使用IValueConverter来实现自定义的绑定转换器,将Code字段转换为相应的图像资源。
以下是一个示例代码,演示如何使用绑定转换器来实现绑定图片列表:
首先,创建一个实现IValueConverter接口的自定义转换器类,用于将Code字段转换为图像资源。该转换器类的Convert()方法将Code字段作为输入参数,并返回相应的图像资源。
// Convert the Code field to the image resource
public class CodeToImageConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is string code)
{
// Construct the image resource URI based on the code
string imageUri = $"/Resources/Logistics/{code}.svg";
// Load the image resource
Uri uri = new Uri(imageUri, UriKind.Relative);
return new BitmapImage(uri);
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
// Not needed for one-way binding
throw new NotSupportedException();
}
}
然后,在XAML中将转换器应用于Tab控件的标题栏的图标部分。使用Image控件显示图像资源,并使用绑定转换器将Code字段转换为图像资源。
<TabControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="30" Height="30">
<Image.Source>
<Binding Path="Code" Converter="{StaticResource CodeToImageConverter}" />
</Image.Source>
</Image>
<Label Content="{Binding Name}" />
</StackPanel>
</DataTemplate>
</TabControl.ItemTemplate>
注意事项:
<Window.Resources>
<local:CodeToImageConverter x:Key="CodeToImageConverter" />
</Window.Resources>
通过实现自定义的绑定转换器并将其应用于XAML的图标部分,就可以将Code字段动态转换为不同的图像资源,实现绑定图片列表的效果。
这样的话,就是把资源地址硬编码到转换器了,和硬编码到视图模型好像没什么大区别,转换器构造函数也没有参数,这个转换器也不能复用了,没有更简单的方式了么?
我把资源放到字典里,转换器用FindResource查找资源的方式,这样转换器可以通用一些,不过找不到的资源直接回全局异常,try捕获不了,不知道是什么原因..
@tltgg: 如果你不想在转换器中硬编码资源地址,并希望转换器可以复用和更简单,你可以考虑使用数据绑定上下文中的属性来传递图像资源。以下是一个示例代码,演示如何在WPF中实现在Tab控件的标题中显示不同的图标,而不使用硬编码的资源地址:
首先,创建一个自定义的标记扩展,用于获取资源的键,并将其传递给转换器:
public class IconExtension : MarkupExtension
{
public string Key { get; set; }
public override object ProvideValue(IServiceProvider serviceProvider)
{
if (string.IsNullOrEmpty(Key))
return null;
// 构造一个包含资源键的对象,并返回
return new IconExtensionData(Key);
}
}
然后,定义一个包含资源键的类,作为转换器的输入:
public class IconExtensionData
{
public string Key { get; }
public IconExtensionData(string key)
{
Key = key;
}
}
接下来,创建一个实现IValueConverter接口的转换器,用于将资源键转换为对应的图像资源:
public class IconConverter : IValueConverter
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
if (value is IconExtensionData iconData)
{
// 使用资源管理器获取对应的图像资源
return Application.Current.Resources[iconData.Key];
}
return null;
}
public object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
throw new NotImplementedException();
}
}
最后,将转换器应用于Tab控件的标题中:
<TabControl>
<TabControl.Resources>
<local:IconConverter x:Key="IconConverter" />
</TabControl.Resources>
<TabItem Header="{Binding Code, Converter={StaticResource IconConverter}, ConverterParameter={local:Icon Key=MyIcon}}" />
</TabControl>
在这个示例中,我们通过将资源键传递给转换器来动态地获取图像资源。在XAML中使用自定义的Icon扩展,以及使用Converter参数将IconExtensionData对象传递给转换器。
通过这种方式,你可以避免将资源地址硬编码到转换器中,同时还能实现转换器的复用和更简单的使用。