开发者

Change displayed image in listbox at runtime

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>开发者_JAVA百科;
            <Image Source="{Binding Id,Converter={StaticResource IdImageConverter}}"/>
            <TextBlock x:Name="id" Text="{Binding Id}" Grid.Column="1"/>
        </Grid>
    </DataTemplate>
</phone:PhoneApplicationPage.Resources>


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>


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.

0

上一篇:

下一篇:

精彩评论

暂无评论...
验证码 换一张
取 消

最新问答

问答排行榜