【问题标题】:How to change the image of listview item based on bind value - UWP如何根据绑定值更改列表视图项的图像 - UWP
【发布时间】:2018-06-29 07:40:57
【问题描述】:

我有一个使用可观察集合绑定值的列表视图。 listview 包含一个带有图像和文本的按钮。根据文本值我想改变按钮的背景颜色,还需要改变图像的来源。我怎样才能做到这一点?

<ListView ItemsSource="{x:Bind ShopArray}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:CurrentShopList2">
            <Button Background="Green" >
                <Grid>
                    <TextBlock Foreground="Black" FontWeight="Bold" Text="{x:Bind IsBooksAvailable}"/>
                    <Image  Source="/Assets/booksAvailable.png" Stretch="None" />
                </Grid>
            </Button>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

如果IsBooksAvailable="Yes"的值,我想将按钮的背景颜色更改为绿色,图像源更改为/Assets/booksAvailable.png。如果IsBooksAvailable="No"的值我想将按钮的背景颜色更改为红色并隐藏图像按钮。

【问题讨论】:

标签: c# xaml listview uwp


【解决方案1】:

对于按钮,您需要一个 IValueConverter。它应该是这样的:

public class BoolToColorConverter : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, string language)
    {

           if ((bool)value)            
               return new SolidColorBrush(Color.FromArgb(255, 0, 255, 0));
           else
               return new SolidColorBrush(Color.FromArgb(255, 255, 0, 0));
    }

    public object ConvertBack(object value, Type targetType, object parameter, string language)
    {
        throw new NotImplementedException();
    }
}

使用此转换器将按钮的颜色属性绑定到 IsBooksAvailable。

对于图像,您可以执行相同的操作,将 Source 属性绑定到文本字段,并在必要时使用转换器将文本调整为正确的路径。 但我更喜欢将图像存储在 ObservableCollection 的 byte[] 属性中,并使用 ByteArrayToImageConverter。

【讨论】:

  • 这里的(布尔值)是什么?如何检查文本是或否?
  • 您将按钮的背景属性绑定到 IsBooksAvailable。这是没有意义的,因为 bool 不能是画笔。所以我们使用转换器。在 convert 方法中,值是您绑定到的值,在本例中为 IsBooksAvailable。 value 是一个对象,所以我们必须将它转换为 bool。然后如果为真则返回绿色,如果为假则返回红色。这是 xaml 中的按钮应如下所示: 但请注意,您必须在 xaml 的资源中定义转换器
  • 在我的情况下是或否不是布尔值。它们是字符串值。在“if ((bool)value)”的地方,我想检查它是否等于“是”/“否”
  • 哦,对不起,我假设它是一个布尔值。因此,您只需转换为字符串并写入:if((string)value == "Yes")。转换器的其余部分可以相同,但我建议捕获 null 和不是“是”或“否”的字符串
【解决方案2】:

这是其他解决方案 - 纯 XAML。除了提到的行为,这也可以通过VisualStateManager来完成:

<ListView ItemsSource="{x:Bind ShopList}">
    <ListView.ItemTemplate>
        <DataTemplate x:DataType="local:ShopItem">
            <UserControl>
                <Button Click="Button_Click">
                    <VisualStateManager.VisualStateGroups>
                        <VisualStateGroup x:Name="AvailableStates">
                            <VisualState x:Name="Default"/>
                            <VisualState x:Name="Available">
                                <VisualState.Setters>
                                    <Setter Target="ItemGrid.Background" Value="Green"/>
                                    <Setter Target="ItemImage.Source" Value="/Assets/Tick.png"/>
                                </VisualState.Setters>
                                <VisualState.StateTriggers>
                                    <StateTrigger IsActive="{x:Bind IsBookAvailable, Mode=OneWay}"/>
                                </VisualState.StateTriggers>
                            </VisualState>
                        </VisualStateGroup>
                    </VisualStateManager.VisualStateGroups>
                    <Grid x:Name="ItemGrid">
                        <TextBlock Foreground="Black" FontWeight="Bold" Text="{x:Bind Title}"/>
                        <Image x:Name="ItemImage" Source="/Assets/NotAvailable.png" Stretch="None" />
                    </Grid>
                </Button>
            </UserControl>
        </DataTemplate>
    </ListView.ItemTemplate>
</ListView>

添加了一些测试的点击:

private void Button_Click(object sender, RoutedEventArgs e)
{
    var shopItem = (e.OriginalSource as FrameworkElement).DataContext as ShopItem;
    shopItem.IsBookAvailable = !shopItem.IsBookAvailable;
}

你可以check at GitHub的整个样本。

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 2011-03-02
    • 2018-02-01
    • 2017-02-21
    • 2021-04-08
    • 2013-04-14
    • 2015-05-24
    • 1970-01-01
    相关资源
    最近更新 更多