Elyasaf755
Elyasaf755

Reputation: 3509

WPF Design Time Data Not Binding To Image

Just like the header says.

The thing is, the image is binding correctly at runtime, and all other properties are binding correctly at design time. Moreover, I've successfully bound images at design-time in other User Controls\Pages.
I've already spent countless hours on this, so I've decided to post here a question.

Here is my problematic XAML:

<local:PageBase x:TypeArguments="vm:StoreViewModel" x:Class="IceCreams.StorePage"
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
  xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
  xmlns:d="http://schemas.microsoft.com/expression/blend/2008" 
  xmlns:local="clr-namespace:IceCreams"
  xmlns:vm="clr-namespace:ViewModels;assembly=ViewModels"
  xmlns:i="clr-namespace:System.Windows.Interactivity;assembly=System.Windows.Interactivity"
  mc:Ignorable="d" 
  d:DesignHeight="720" d:DesignWidth="1080"
  Title="{Binding CurrentStore.Name}"
  d:DataContext="{x:Static vm:StoreDesignModel.Instance}">

<i:Interaction.Triggers>
    <i:EventTrigger EventName="Loaded">
        <i:InvokeCommandAction Command="{Binding LoadedCommand}" />
    </i:EventTrigger>
</i:Interaction.Triggers>

<Grid>
    <Grid.RowDefinitions>
        <RowDefinition Height="200" />
        <RowDefinition Height="*" />
    </Grid.RowDefinitions>

    <!-- Page Header (Upper Row)-->
    <Grid Grid.Row="0">
        <Grid.ColumnDefinitions>
            <ColumnDefinition Width="200" />
            <ColumnDefinition Width="*"/>
        </Grid.ColumnDefinitions>

        <!-- Store Header -->
        <StackPanel HorizontalAlignment="Center" VerticalAlignment="Center" Height="200" Grid.ColumnSpan="2">

            <StackPanel Orientation="Horizontal" Margin="0 50 0 0">

                <!-- Store Logo. ***************THIS IS THE PROBLEMATIC IMAGE****************** -->
                <Image Stretch="UniformToFill" Margin="0 0 20 0"
                       Height="80" Width="80"
                       Source="{Binding CurrentStore.ImageUrl, 
                                        Converter={local:ImageSourceConverter}}" />

                <!-- Store Name -->
                <TextBlock Text="{Binding CurrentStore.Name}" 
                       FontSize="60" FontFamily="Gabriola" FontWeight="SemiBold"
                       VerticalAlignment="Center" HorizontalAlignment="Center" />

            </StackPanel>

            <!-- Store Address Line -->
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
                <TextBlock Text="{StaticResource FontAwesomeLocationIcon}" Style="{StaticResource IconTextBlock}" Margin="0 0 5 5"/>
                <TextBlock Text="{Binding CurrentStore.Address}" />
            </StackPanel>

            <!-- Store Phone Number -->
            <StackPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center">
                <TextBlock Text="{StaticResource FontAwesomePhoneIcon}" Style="{StaticResource IconTextBlock}" Margin="0 0 5 0"/>
                <TextBlock Text="{Binding CurrentStore.Phone}" />
            </StackPanel>
        </StackPanel>

    </Grid>

    <!-- Page Content (Lower Row) -->
    <Grid Grid.Row="1">
        <local:StoreListControl />
    </Grid>
</Grid>



Here is my ViewModel:

using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Input;

namespace ViewModels
{
    public class StoreViewModel : ViewModelBase
    {
        #region Public Properties

        public Store CurrentStore { get; set; }
        public List<StoreListItemViewModel> Items { get; set; } = new List<StoreListItemViewModel>();

        #endregion

        #region Commands

        /// <summary>
        /// The command to login
        /// </summary>
        public ICommand LoadedCommand { get; set; }

        #endregion

        #region Public Constructor

        public StoreViewModel()
        {
            // Create commands
            LoadedCommand = new RelayCommand(async () => await Loaded());
        }

        #endregion


        #region Async Methods

        public async Task Loaded()
        {
            //TODO: Delete
            PopulateStore();

            await Task.Delay(1);
        }

        #endregion

        //TODO: Delete
        private void PopulateStore()
        {

            CurrentStore = new Store
            {
                Name = "Store View Model",
                Address = new Address
                {
                    Street = "Sufa 4",
                    City = "Beit El",
                    Country = "Israel",
                },

                ImageUrl = @"/IceCreams;component/Images/shop4.png",
                Phone = "0546401267",
                Icecreams = new List<Icecream>
                {
                    new Icecream
                    {
                        Name = "Store View Model 1",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item1.jpg",
                        Description = "my icecream 1",
                        Price = "10",
                    },
                    new Icecream
                    {
                        Name = "Store View Model 2",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item2.jpg",
                        Description = "my icecream 2",
                        Price = "20",
                    },
                    new Icecream
                    {
                        Name = "Store View Model 3",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item3.jpg",
                        Description = "my icecream 3",
                        Price = "30",
                    },
                    new Icecream
                    {
                        Name = "Store View Model 4",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item1.jpg",
                        Description = "my icecream 4",
                        Price = "40",
                    },
                },
            };

            if (CurrentStore == null || CurrentStore.Icecreams == null)
                return;

            foreach (Icecream icecream in CurrentStore.Icecreams)
            {
                Items.Add(new StoreListItemViewModel
                {
                    Name = icecream.Name,
                    ImageUrl = icecream.ImageUrl,
                    Description = icecream.Description,
                    Price = icecream.Price,
                });
            }
        }
    }
}



Here is my DesignModel:

using Models;
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

namespace ViewModels
{
    public class StoreDesignModel : StoreViewModel
    {
        #region Singleton

        /// <summary>
        /// A single instance of the design model
        /// </summary>
        public static StoreDesignModel Instance => new StoreDesignModel();

        #endregion

        #region Constructor

        public StoreDesignModel()
        {
            PopulateStore();
        }

        #endregion

        private void PopulateStore()
        {
            CurrentStore = new Store
            {
                Name = "Store Design Model",
                Address = new Address
                {
                    Street = "Sufa 4",
                    City = "Beit El",
                    Country = "Israel",
                },

                ImageUrl = @"/IceCreams;component/Images/logo.png",
                Phone = "0546401267",

                Icecreams = new List<Icecream>
                {
                    new Icecream
                    {
                        Name = "Store Design Model 1",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item1.jpg",
                        Description = "Item 1",
                        Price = "10",
                    },
                    new Icecream
                    {
                        Name = "Store Design Model 2",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item2.jpg",
                        Description = "Item 2",
                        Price = "20",
                    },
                    new Icecream
                    {
                        Name = "Store Design Model 3",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item3.jpg",
                        Description = "Item 3",
                        Price = "30",
                    },
                    new Icecream
                    {
                        Name = "Store Design Model 4",
                        ImageUrl = @"/IceCreams;component/Images/Items/icecream_item1.jpg",
                        Description = "Item 4",
                        Price = "40",
                    },
                },
            };

            if (CurrentStore == null || CurrentStore.Icecreams == null)
                return;

            foreach (Icecream icecream in CurrentStore.Icecreams)
            {
                Items.Add(new StoreListItemViewModel
                {
                    Name = icecream.Name,
                    ImageUrl = icecream.ImageUrl,
                    Description = icecream.Description,
                    Price = icecream.Price,
                });
            }
        }
    }
}



My image converter (shouldn't be a problem though, because it's doing its job everywhere else):

using System;
using System.Collections.Generic;
using System.Globalization;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace IceCreams
{
    public class ImageSourceConverter : ValueConverterBase<ImageSourceConverter>
    {
        public override object Convert(object value, Type targetType, object parameter, CultureInfo culture)
        {
            BitmapImage result;

            if (targetType == typeof(ImageSource))
            {
                if (value is string)
                {
                    string str = (string)value;

                    return new BitmapImage(new Uri(str, UriKind.RelativeOrAbsolute));
                }
                else if (value is Uri)
                {
                    Uri uri = (Uri)value;

                    return new BitmapImage(uri);
                }
            }

            return value;
        }

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



My Images paths:
enter image description here

At runtime (The image I'm talking about it the one to the left of the big header "Store View Model"):
enter image description here



At design-time (Notice the empty square to the left of the big header "Store Design Model", the image should be there):
enter image description here

Upvotes: 0

Views: 126

Answers (0)

Related Questions