首页 新闻 会员 周边

WPF如何绑定图片列表

0
悬赏园豆:200 [已解决问题] 解决于 2023-07-14 09:35
<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>

但我不想在视图模型里加字段,难道要用类型转换器?

tltgg的主页 tltgg | 初学一级 | 园豆:4
提问于:2023-07-13 15:35
< >
分享
最佳答案
0

要实现在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>

注意事项:

  1. 在XAML文件中,需要在资源的定义部分引入和声明绑定转换器:
<Window.Resources>
    <local:CodeToImageConverter x:Key="CodeToImageConverter" />
</Window.Resources>
  1. 确保将图像资源的生成操作设置为"嵌入的资源",以便能够在XAML中正确加载图像资源。

通过实现自定义的绑定转换器并将其应用于XAML的图标部分,就可以将Code字段动态转换为不同的图像资源,实现绑定图片列表的效果。

收获园豆:200
lanedm | 老鸟四级 |园豆:2378 | 2023-07-13 18:01

这样的话,就是把资源地址硬编码到转换器了,和硬编码到视图模型好像没什么大区别,转换器构造函数也没有参数,这个转换器也不能复用了,没有更简单的方式了么?

tltgg | 园豆:4 (初学一级) | 2023-07-13 19:39

我把资源放到字典里,转换器用FindResource查找资源的方式,这样转换器可以通用一些,不过找不到的资源直接回全局异常,try捕获不了,不知道是什么原因..

tltgg | 园豆:4 (初学一级) | 2023-07-14 08:08

@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对象传递给转换器。

通过这种方式,你可以避免将资源地址硬编码到转换器中,同时还能实现转换器的复用和更简单的使用。

lanedm | 园豆:2378 (老鸟四级) | 2023-07-14 09:31
清除回答草稿
   您需要登录以后才能回答,未注册用户请先注册