Reputation: 3509
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();
}
}
}
At runtime (The image I'm talking about it the one to the left of the big header "Store View Model"):
At design-time (Notice the empty square to the left of the big header "Store Design Model", the image should be there):
Upvotes: 0
Views: 126