在运行时更改列表框中显示的图像

发布于 2024-12-04 02:35:47 字数 2248 浏览 0 评论 0原文

我有一个绑定到 Observable 集合的列表框,它根据其中的数据显示不同的图像,如下所示:

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="PersonTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding Path=ImagePath}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

然后我稍后使用它:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ListBox x:Name="personListBox" ItemTemplate="{StaticResource PersonTemplate}" 
             ItemsSource="{Binding PersonCollection}"/>
</Grid>

但这意味着我已经创建了 ImagePath 属性作为 Person 的一部分,这并不真正正确,因为它是 ViewModel 而不是模型的一部分。是否可以以某种方式将绑定添加到 ViewModel 中,以便我可以将 Id 传递到相应的更改图像中?

编辑: 事实上,我在玩了一些之后找到了一种方法,但我不确定这是否是一种明智的方法。我创建了一个 ValueConverter 并用它来更改值。

public class IdToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int id = (int)value;
        string img;

        switch (id)
        {
            case 1: img = @"Resources/Image/image1.png"; break;
            case 2: img = @"Resources/Image/image2.png"; break;
            default: img = @"Resources/Image/unknown.png"; break;
        }

        return img;
    }

然后这有效:

<phone:PhoneApplicationPage.Resources>
    <local:IdToImageConverter x:Key="IdImageConverter"/>
    <DataTemplate x:Key="PersonTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding Id,Converter={StaticResource IdImageConverter}}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

I have a Listbox bound to an Observable collecton that has a different image displayed depending on the data within it like so:

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="PersonTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding Path=ImagePath}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

I then use it later:

<Grid x:Name="ContentPanel" Grid.Row="1" Margin="12,0,12,0">
    <ListBox x:Name="personListBox" ItemTemplate="{StaticResource PersonTemplate}" 
             ItemsSource="{Binding PersonCollection}"/>
</Grid>

However this means I have created the ImagePath property as part of the Person which isn't really correct, as it is part of the ViewModel rather than the model. Is it possible to somehow to add a binding into the ViewModel that I can pass the Id into an change the image accordingly?

EDIT:
I actually after some playing found a way to do it but I am not sure if it is a sensible approach. I created a ValueConverter and used it to change the value.

public class IdToImageConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, System.Globalization.CultureInfo culture)
    {
        int id = (int)value;
        string img;

        switch (id)
        {
            case 1: img = @"Resources/Image/image1.png"; break;
            case 2: img = @"Resources/Image/image2.png"; break;
            default: img = @"Resources/Image/unknown.png"; break;
        }

        return img;
    }

Then this works:

<phone:PhoneApplicationPage.Resources>
    <local:IdToImageConverter x:Key="IdImageConverter"/>
    <DataTemplate x:Key="PersonTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image Source="{Binding Id,Converter={StaticResource IdImageConverter}}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(2

梦一生花开无言 2024-12-11 02:35:47

这是一个常见的要求,也是最常见的解决方案,它对特定的 IValueConverter 进行编码,如您的编辑所示。然而,由于这是一个常见的要求,因此最好创建一个可用于处理此问题的通用代码块。

请参阅此博客了解常见转换器实现的示例(其名为 StringToObjectConverter 但不要因此而失望)。

然后您可以将转换器添加到视图中:-

         <local:StringToObjectConverter x:Key="TypeToImageSource">
             <ResourceDictionary>
                 <BitmapImage UriSource="Resources/Image/image1.png" x:Key="1" />
                 <BitmapImage UriSource="Resources/Image/image2.png" x:Key="2" />
                 <BitmapImage UriSource="Resources/Image/unknown.png" x:Key="__default__" /> 
            </ResourceDictionary>
         </local:StringToObjectConverter>

This is a common requirement and the most common solution it code a specific IValueConverter as your edit shows. However since its a common requirement it would be better to create a common chunk of code that could be used to handle this.

See this blog for an example of a common converter implementation (its called StringToObjectConverter but don't let that put you off).

You could then add a converter to the view:-

         <local:StringToObjectConverter x:Key="TypeToImageSource">
             <ResourceDictionary>
                 <BitmapImage UriSource="Resources/Image/image1.png" x:Key="1" />
                 <BitmapImage UriSource="Resources/Image/image2.png" x:Key="2" />
                 <BitmapImage UriSource="Resources/Image/unknown.png" x:Key="__default__" /> 
            </ResourceDictionary>
         </local:StringToObjectConverter>
烟─花易冷 2024-12-11 02:35:47

我不确定我是否正确理解你的问题。您是说 ImagePath 不是 PersonCollection 集合的属性,它属于其他集合吗?如果是这样,您可以通过指定 DataContext 来引用它,如下所示:

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="PersonTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image DataContext="{Binding ImageCollection}" 
                   Source="{Binding Path=ImagePath}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

编辑:
重新阅读您的问题,我认为您是在问如何绑定根据 PersonCollectionId 属性选择的图像。为此,请在 ViewModel 中创建一个名为 ImageCollection 的集合,其中包含属性 ImagePath,其中包含与 Id 列表对应创建的图像列表出现在 PersonCollection 中并如上所示绑定它。

I'm not sure I understand your question correctly. Are you saying that ImagePath is not a property of the PersonCollection collection, that it belongs to some other collection? If so, you can reference it by specifying the DataContext as follows:

<phone:PhoneApplicationPage.Resources>
    <DataTemplate x:Key="PersonTemplate">
        <Grid>
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Image DataContext="{Binding ImageCollection}" 
                   Source="{Binding Path=ImagePath}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>

EDIT:
Re-reading your question I think you're asking how to bind an image that is selected depending on the Id property of PersonCollection. To do that, create a collection called ImageCollection in your ViewModel, containing the property ImagePath, which contains a list of images that are created corresponding to the list of Ids appearing in PersonCollection and bind it as shown above.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文