如何将图像源绑定到动态可变属性?

时间:2019-05-22 12:31:44

标签: xaml mvvm xamarin.forms binding

我很想在ListView框架中显示不同的图像,具体取决于模型中的ServiceName。

这是我的模型:

public class IrrigNetModelItem
{
    public int ID { get; set; }
    public string Message { get; set; }
    public DateTime Date { get; set; }
    public string DateText { get; set; }
    public int StationId { get; set; }
    public string StationName { get; set; }
    public float StationLongitude { get; set; }
    public float StationLatitude { get; set; }
    public int ServiceId { get; set; }
    public string ServiceName { get; set; }       
}

这是ViewModel的一部分

    public ObservableCollection<IrrigNetModelItem> IrrigNetCollection { get; set; } = new ObservableCollection<IrrigNetModelItem>();
    public async void GetData()
    {
        base.OnAppearing();
        dialog.Show();
        var token = LocalData.Token;
        var data = await IrrigNetService.GetServices(token, "en");
        var irrigNetModel = new IrrigNetModelItem();
        foreach (var d in data.items)
        {
            IrrigNetCollection.Add(d);
            if (d.ServiceName == "irrigNET")
            {
                IrrigCounter++;
                //FrameImage = "service_irrig_img.png";
                //FrameHeaderColor = Color.FromHex("#33A8F7");                    
            }
            else
            {
                AlertCounter++;
                //FrameImage = "alert.png";
                //FrameHeaderColor = Color.FromHex("#2BB24B");                  
            }                
        }
        dialog.Hide();
    }

目前,服务名称可以是“ irrigNET”和“ alertNET”,并取决于我要在View的ListView中设置不同的图像源。

这是视图:

    <ListView
        ItemsSource="{Binding IrrigNetCollection}"
        IsVisible="{Binding IsListVisible}"
        ItemSelected="FrameList_ItemSelected"
        HasUnevenRows="False"
        x:Name="FrameList" 
        Grid.Row="2"
        RowHeight="190"
        Margin="0,0,0,20"
        SeparatorVisibility="None"
        HeightRequest="0">
        <ListView.ItemTemplate Padding="0">
            <DataTemplate>
                <ViewCell>
                    <Frame
                           HasShadow="True"
                           Grid.ColumnSpan="5"
                           HorizontalOptions="FillAndExpand"
                           VerticalOptions="FillAndExpand"
                           BackgroundColor="#f4f4f4" 
                           BorderColor="LightGray"
                           CornerRadius="10"
                           Margin="25,10,25,10"
                           Padding="0">
                        <Grid
                            VerticalOptions="FillAndExpand"
                            HorizontalOptions="FillAndExpand"
                            IsEnabled="True">
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="5"/>
                                <ColumnDefinition Width="40"/>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition Width="*"/>
                                <ColumnDefinition Width="20"/>
                                <ColumnDefinition Width="5"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="13"/>
                                <RowDefinition Height="35"/>
                                <RowDefinition Height="*"/>
                                <RowDefinition Height="30"/>
                            </Grid.RowDefinitions>
                            <BoxView Color="{Binding Path=BindingContext.FrameHeaderColor, Source={x:Reference FrameList}}" 
                                     Grid.Row="0" 
                                     Grid.ColumnSpan="6" 
                                     HorizontalOptions="FillAndExpand" 
                                     VerticalOptions="StartAndExpand"/>

                            <Image Source="{Binding Path=BindingContext.FrameImage, Source={x:Reference FrameList}}"
                                   Grid.Column="1"
                                   Grid.Row="1"
                                   Grid.RowSpan="3"
                                   Margin="0,20,0,0"/>

                                <Image Source="{Binding Path=BindingContext.FrameIcon, Source={x:Reference FrameList}}"
                                   Grid.Column="2"
                                   Grid.Row="1"
                                   HorizontalOptions="Start"
                                   VerticalOptions="Center"
                                   HeightRequest="17"
                                   WidthRequest="17"/>

                            <Label 
                                   Text="{Binding StationName}"
                                   VerticalTextAlignment="Start"
                                   HorizontalTextAlignment="Start"
                                   HorizontalOptions="Start"
                                   VerticalOptions="Center"
                                   Margin="3,3,0,0"
                                   FontSize="18"
                                   Grid.Column="3"
                                   Grid.Row="1"
                                   FontFamily="{StaticResource BalooBhai}"
                                   TextColor="#262f41"/>

                            <Image Source="service_arrow.png"
                                   Grid.Column="4"
                                   Grid.Row="2"
                                   VerticalOptions="Center"
                                   HorizontalOptions="Center"
                                   HeightRequest="18"
                                   WidthRequest="18"/>

                            <Image Source="clock.png"
                                   Grid.Column="2"
                                   Grid.Row="3"
                                   HorizontalOptions="Start"
                                   VerticalOptions="Center"/>

                            <Label Text="{Binding DateText}"
                                   FontSize="14"
                                   FontFamily="{StaticResource SegoeUIB}"
                                   Grid.Column="3"
                                   Grid.Row="3"
                                   HorizontalTextAlignment="Start"
                                   VerticalTextAlignment="Start"
                                   Margin="3,0,0,0"
                                   TextColor="#262f41"/>

                            <Label Text="{Binding Message}"
                                   Grid.Column="3"
                                   Grid.Row="2"
                                   VerticalTextAlignment="Start"
                                   HorizontalOptions="Center"
                                   VerticalOptions="Center"
                                   FontFamily="{StaticResource SegoeUI}" FontSize="13"
                                   TextColor="#262f41"
                                   Margin="0,0,10,0"/>
                        </Grid>
                    </Frame>
                </ViewCell>
            </DataTemplate>
        </ListView.ItemTemplate>
        <ListView.GroupHeaderTemplate>
            <DataTemplate>
                <ViewCell Height="40">
                    <StackLayout Orientation="Horizontal"
                             BackgroundColor="#3498DB"
                             VerticalOptions="FillAndExpand">
                        <Label Text="TeStIrAnjE"
                           TextColor="White"
                           VerticalOptions="Center" />
                        <Button Text="Edit"
                                        TextColor="White" 
                                        FontSize="20"/>
                    </StackLayout>
                </ViewCell>
            </DataTemplate>
        </ListView.GroupHeaderTemplate>
    </ListView>

您会看到我在Image标签中尝试过的内容,但目前没有显示任何图像。 这是我尝试在ViewModel中使用的比例:

    //public string FrameIrrigImage { get; set; } //= "service_irrig_img.png";
    //public Color FrameIrrigHeaderColor { get; set; } //= Color.FromHex("#33A8F7");

    //public string FrameAlertImage { get; set; } //= "alert.png";
    //public Color FrameAlertHeaderColor { get; set; } // = Color.FromHex("#2BB24B");


    //public string typeNet { get; set; }
    //public Color typeNETcolortext { get; set; }
    //public Color allertNETcolortext { get; set; }

这是我要达到的目标: enter image description here

但这是我得到的: enter image description here

(您可以看到BoxView heder也是蓝色/彩色,但是我将在Image示例中了解如何更改它)

我也尝试使用属性来实现它:

public string FrameImage { get; set; } 
public Color FrameHeaderColor { get; set; }

在for循环中设置它们的值,并在xaml中绑定它们,但是所有这些(图像和颜色)都已设置为ListView中的最后一个元素

1 个答案:

答案 0 :(得分:0)

正如Jason所说,有两种方法,一种是通过ServiceName使用IValueConverter,另一种是在模型中添加FrameImage,然后通过serviceName更改FrameImage。

我做一个简单的介绍,如果在模型中添加FrameImage,请实现INotifyPropertyChanged接口。

<ContentPage
x:Class="App4.Page9"
xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:converter="clr-namespace:App4">
<ContentPage.Resources>
    <converter:convert1 x:Key="converterimage" />
</ContentPage.Resources>
<ContentPage.Content>
    <StackLayout>
        <ListView ItemsSource="{Binding model2s}">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <StackLayout Orientation="Horizontal">
                            <Label Text="{Binding firstname}" />
                            <Image Source="{Binding imagepath}" />
                            <Image Source="{Binding Id, Converter={StaticResource converterimage}}" />
                        </StackLayout>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </StackLayout>
</ContentPage.Content>

public partial class Page9 : ContentPage
{
    public ObservableCollection<model2> model2s { get; set; }      
    public Page9 ()
    {
        InitializeComponent ();
        model2s = new ObservableCollection<model2>()
        {
            new model2(){Id=1,firstname="cherry"},
            new model2(){Id=2,firstname="mattew"},
            new model2(){Id=3,firstname="annine"},
            new model2(){Id=4,firstname="barry"}
        };

        foreach(model2 m in model2s)
        {
            if(m.Id%2==0)
            {
                m.imagepath = "a1.jpg";
            }
            else
            {
                m.imagepath = "a2.jpg";
            }
        }
        this.BindingContext = this;

    }

}

public class model2:ViewModelBase
{
    public int Id { get; set; }
    public string firstname { get; set; }

    private string _imagepath;
    public string imagepath
    {
        get { return _imagepath; }
        set
        {
            _imagepath = value;
            RaisePropertyChanged("imagepath");

        }
    }
}

转换器:

 class convert1 : IValueConverter
{
    public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
    {
        int id = (int)value;
        if(id%2==0)
        {
            return "a1.jpg";
        }
        else
        {
            return "a2.jpg";
        }
    }

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