最新消息:雨落星辰是一个专注网站SEO优化、网站SEO诊断、搜索引擎研究、网络营销推广、网站策划运营及站长类的自媒体原创博客

c# - Image Source is not working from view model for RadioButton in .NET MAUI - Stack Overflow

programmeradmin2浏览0评论

Here is MainPage.xaml markup:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns=";
             xmlns:x=";
             xmlns:local="clr-namespace:_26_RadioButton.ViewModels"
             xmlns:model="clr-namespace:_26_RadioButton.Models"
             x:DataType="local:AnimalsViewModel"
             x:Class="_26_RadioButton.MainPage">

    <ContentPage.BindingContext>
        <local:AnimalsViewModel />
    </ContentPage.BindingContext>

    <ScrollView>
        <StackLayout Padding="10">
            <!-- Example 1-->
            <Label Text="What is your favourite animal?" Padding="10, 0, 0, 0"
                   FontSize="20" TextColor="Teal" />

            <StackLayout Margin="10, 0">
                <RadioButton Content="Elephant" />
                <RadioButton Content="Rhinoceros" />
                <RadioButton Content="Leopard" />
                <RadioButton Content="Monkey" />
            </StackLayout>
            
            <!-- Example 2 (Display arbitrary content) -->
            <Label Text="What is your fabourite bird?" Padding="10, 0"
                   FontSize="20" TextColor="BlueViolet" />

            <StackLayout Margin="10, 0">
                <CollectionView ItemsSource="{Binding Animals}">
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="model:Animal">
                            <StackLayout>
                                <RadioButton>
                                    <RadioButton.Content>
                                        <Image Source="{Binding ImageURL}" />
                                    </RadioButton.Content>
                                </RadioButton>
                                <Label Text="{Binding Name_of_animal}" HorizontalOptions="Center" />
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </StackLayout>
        </StackLayout>
    </ScrollView>

</ContentPage>

Here is the MainPage.xaml.cs code file:

using _26_RadioButton.ViewModels;

namespace _26_RadioButton
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            BindingContext = new AnimalsViewModel();
        }
    }
}

Here is the view model class:

using System.Collections.ObjectModel;
using _26_RadioButton.Models;

namespace _26_RadioButton.ViewModels
{
    public class AnimalsViewModel
    {
        public ObservableCollection<Animal>? Animals { get; set; }

        public AnimalsViewModel() 
        {
            Animals = [
                new Animal { Name_of_animal="Indian Peafowl", ImageURL=":Pavo_cristatus_male.jpg" },
                new Animal { Name_of_animal="Manipur Bush Quail", ImageURL=".png" },
                new Animal { Name_of_animal="White Crowned Sparrow", ImageURL=".jpg" },
                new Animal { Name_of_animal="Little Grebe", ImageURL=".jpg/330px-Zwergtaucher_060319_3.jpg" }
            ];
        }
    }
}

I am using .NET 9 SDK. In the output it is not showing the image for the radio button.

I am facing the issue that the image from the view model class is not fetching properly, however it can fetch the text but unable to fetch the image.

In the output it is showing Microsoft.Maui.Controls.Image

Expected output: image output

Here is MainPage.xaml markup:

<?xml version="1.0" encoding="utf-8" ?>
<ContentPage xmlns="http://schemas.microsoft/dotnet/2021/maui"
             xmlns:x="http://schemas.microsoft/winfx/2009/xaml"
             xmlns:local="clr-namespace:_26_RadioButton.ViewModels"
             xmlns:model="clr-namespace:_26_RadioButton.Models"
             x:DataType="local:AnimalsViewModel"
             x:Class="_26_RadioButton.MainPage">

    <ContentPage.BindingContext>
        <local:AnimalsViewModel />
    </ContentPage.BindingContext>

    <ScrollView>
        <StackLayout Padding="10">
            <!-- Example 1-->
            <Label Text="What is your favourite animal?" Padding="10, 0, 0, 0"
                   FontSize="20" TextColor="Teal" />

            <StackLayout Margin="10, 0">
                <RadioButton Content="Elephant" />
                <RadioButton Content="Rhinoceros" />
                <RadioButton Content="Leopard" />
                <RadioButton Content="Monkey" />
            </StackLayout>
            
            <!-- Example 2 (Display arbitrary content) -->
            <Label Text="What is your fabourite bird?" Padding="10, 0"
                   FontSize="20" TextColor="BlueViolet" />

            <StackLayout Margin="10, 0">
                <CollectionView ItemsSource="{Binding Animals}">
                    <CollectionView.ItemTemplate>
                        <DataTemplate x:DataType="model:Animal">
                            <StackLayout>
                                <RadioButton>
                                    <RadioButton.Content>
                                        <Image Source="{Binding ImageURL}" />
                                    </RadioButton.Content>
                                </RadioButton>
                                <Label Text="{Binding Name_of_animal}" HorizontalOptions="Center" />
                            </StackLayout>
                        </DataTemplate>
                    </CollectionView.ItemTemplate>
                </CollectionView>
            </StackLayout>
        </StackLayout>
    </ScrollView>

</ContentPage>

Here is the MainPage.xaml.cs code file:

using _26_RadioButton.ViewModels;

namespace _26_RadioButton
{
    public partial class MainPage : ContentPage
    {
        public MainPage()
        {
            InitializeComponent();
            BindingContext = new AnimalsViewModel();
        }
    }
}

Here is the view model class:

using System.Collections.ObjectModel;
using _26_RadioButton.Models;

namespace _26_RadioButton.ViewModels
{
    public class AnimalsViewModel
    {
        public ObservableCollection<Animal>? Animals { get; set; }

        public AnimalsViewModel() 
        {
            Animals = [
                new Animal { Name_of_animal="Indian Peafowl", ImageURL="https://en.wikipedia./wiki/File:Pavo_cristatus_male.jpg" },
                new Animal { Name_of_animal="Manipur Bush Quail", ImageURL="https://i.pinimg/originals/de/cf/60/decf602380bbc3c319e38799f26de3b5.png" },
                new Animal { Name_of_animal="White Crowned Sparrow", ImageURL="https://a-z-animals/media/2022/10/White-Crowned-Sparrow.jpg" },
                new Animal { Name_of_animal="Little Grebe", ImageURL="https://upload.wikimedia./wikipedia/commons/thumb/c/c1/Zwergtaucher_060319_3.jpg/330px-Zwergtaucher_060319_3.jpg" }
            ];
        }
    }
}

I am using .NET 9 SDK. In the output it is not showing the image for the radio button.

I am facing the issue that the image from the view model class is not fetching properly, however it can fetch the text but unable to fetch the image.

In the output it is showing Microsoft.Maui.Controls.Image

Expected output: image output

Share Improve this question edited Mar 7 at 17:19 marc_s 756k184 gold badges1.4k silver badges1.5k bronze badges asked Mar 7 at 17:15 S M De SavicS M De Savic 12 bronze badges 2
  • 2 I'd suggest trying to use an Image control first to rule out if the issue is in the binding, the image source, or the control itself. – Jason Commented Mar 7 at 18:03
  • Is anything showing where the image would be located? – jdweng Commented Mar 7 at 18:13
Add a comment  | 

1 Answer 1

Reset to default 1

I had to make a correction to the first ImageURL since it pointed to a web page not an actual image:

    [
#if BADURL
        new Animal { Name_of_animal="Indian Peafowl", ImageURL="https://en.wikipedia./wiki/File:Pavo_cristatus_male.jpg" },
#endif
        new Animal { Name_of_animal="Indian Peafowl", ImageURL="https://upload.wikimedia./wikipedia/commons/4/45/Pavo_cristatus_male.jpg" },
        new Animal { Name_of_animal="Manipur Bush Quail", ImageURL="https://i.pinimg/originals/de/cf/60/decf602380bbc3c319e38799f26de3b5.png" },
        new Animal { Name_of_animal="White Crowned Sparrow", ImageURL="https://a-z-animals/media/2022/10/White-Crowned-Sparrow.jpg" },
        new Animal { Name_of_animal="Little Grebe", ImageURL="https://upload.wikimedia./wikipedia/commons/thumb/c/c1/Zwergtaucher_060319_3.jpg/330px-Zwergtaucher_060319_3.jpg" }
    ];

The second change I had to make was that the inner RadioButton.Content needed the BindingContext to be reapplied. So, I took a copy of BindingContext from the RadioButton and applied it to a the first child in RadioButton.Content, e.g.

<CollectionView ItemsSource="{Binding Animals}">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="local:Animal">
            <StackLayout>
                <RadioButton x:Name="radioButton">
                    <RadioButton.Content>
                        <Grid
                            x:DataType="local:Animal"
                            BindingContext="{Binding BindingContext, x:DataType=RadioButton, Source={Reference radioButton}}"
                            HeightRequest="64"
                            WidthRequest="64">
                            <Image Source="{Binding ImageURL}" />
                        </Grid>
                    </RadioButton.Content>
                </RadioButton>
                <Label HorizontalOptions="Center" Text="{Binding Name_of_animal}" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>

One way of tidying this up is to turn your custom RadioButton into a component, e.g.

// CustomRadioButton.cs
public class CustomRadioButton : RadioButton
{
    private Image image;
    public static readonly BindableProperty ImageURLProperty = BindableProperty.Create(nameof(ImageURL), typeof(string), typeof(CustomRadioButton), string.Empty);
    public string ImageURL
    {
        get => (string)GetValue(ImageURLProperty);
        set => SetValue(ImageURLProperty, value);
    }
    public CustomRadioButton()
    {
        Content = image = new Image()
        {
            WidthRequest = 64,
            HeightRequest = 64,
        };
        image.SetBinding(Image.SourceProperty, BindingBase.Create<CustomRadioButton, string>(static t => t.ImageURL, mode: BindingMode.OneWay, source: this));
    }
}

Now, with the above component, the XAML will look a lot more tidier:

<CollectionView ItemsSource="{Binding Animals}">
    <CollectionView.ItemTemplate>
        <DataTemplate x:DataType="local:Animal">
            <StackLayout>
                <local:CustomRadioButton ImageURL="{Binding ImageURL}" />
                <Label HorizontalOptions="Center" Text="{Binding Name_of_animal}" />
            </StackLayout>
        </DataTemplate>
    </CollectionView.ItemTemplate>
</CollectionView>
发布评论

评论列表(0)

  1. 暂无评论