ViewModelLocator in PRISM (Unity) does not work in modules - c#

I am following the Brian Lagunas's tutorial and have a question.
We have a small application setup with PRISM 6 and Unity bootstrapper. I want to use the ViewModelLocator to bind a ViewModel to my view. This works in the "base module" (the one with Shell and bootstrapper), but it seems that there are some issues when using it in other modules.
Below you can find the classes for View (XAML and code behind) and for ViewModel. The binding works if I set the DataContext in the code behind manually. while debugging the code I found out that the ViewModel class is never instantiated so I guess the VML cannot find the VM because of wrong configuration. But as far as I can see the naming conventions are fulfilled.
Can you find the issue or have an idea what configuration I did forget?
View(code behind):
namespace CommunicationModule.Views
{
public partial class CommunicationView : UserControl, IView
{
public CommunicationView()
{
InitializeComponent();
}
}
}
View XAML:
<UserControl
x:Class="CommunicationModule.Views.CommunicationView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:View="clr-namespace:CommunicationModule.Views"
xmlns:prism="http://prismlibrary.com/"
prism:ViewModelLocator.AutoWireViewModel="True">
<Grid DataContext="{Binding ModelList, UpdateSourceTrigger=PropertyChanged}" Width="320" Height="300">
<Grid.Resources>
<DataTemplate x:Key="DataTemplate">
<Border Name="border" BorderBrush="DarkSlateBlue" BorderThickness="2"
CornerRadius="2" Padding="5" Margin="5">
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition MaxWidth="30"/>
<ColumnDefinition />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Image Grid.Row="0" Grid.Column="0" Source="{Binding Path=IconUri}" HorizontalAlignment="Left" />
<TextBlock Grid.Row="0" Grid.Column="1" Text="{Binding Path=Title}" FontSize="12" FontWeight="Bold" />
<TextBlock Grid.Row="1" Grid.Column="1" Text="{Binding Path=ContentShort}"/>
</Grid>
</Border>
</DataTemplate>
</Grid.Resources>
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<!-- UI -->
<DockPanel Grid.ColumnSpan="2" Margin="0,0,10,0">
<!-- Title -->
<Label DockPanel.Dock="Top" FontSize="18" Margin="5" Content="Wichtige Meldungen"/>
<!-- Data template is specified by the ItemTemplate attribute -->
<ScrollViewer>
<ListBox Name="listBox"
SelectionMode="Single"
ItemsSource="{Binding}"
ItemTemplate="{StaticResource DataTemplate}"
HorizontalContentAlignment="Stretch"
IsSynchronizedWithCurrentItem="True"
Margin="5,0,5,5" Width="280"/>
</ScrollViewer>
</DockPanel>
</Grid>
</UserControl>
ViewModel:
namespace CommunicationModule.ViewModels
{
public class CommunicationViewViewModel : BindableBase
{
private List<CommunicationModel> _modelList = (new CommunicationModelBO()).getCommunicationItems(); //= new List<CommunicationModel>();
private readonly IRegionManager _regionManager;
public List<CommunicationModel> ModelList
{
get { return _modelList; }
set { SetProperty<List<CommunicationModel>>(ref _modelList, value); }
}
public CommunicationViewViewModel(IRegionManager regionManager)
{
_regionManager = regionManager;
}
}
}

You can not let your usercontrol's name end with View,if you do so, the AutoWireViewModel won't work. So please change your usercontrols name to Communication and viewmodels name to CommunicationViewModel.

Related

How to open child window in mainwindow in MMVM WPF

I have 3 screens
Mainwindow.xaml
<Window x:Class="PatientAdminTool.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
>
<Window.DataContext>
<vm:MainViewModel></vm:MainViewModel>
</Window.DataContext>
<WindowChrome.WindowChrome>
<WindowChrome
CaptionHeight="0"/>
</WindowChrome.WindowChrome>
<ContentControl >
<v:PatientWindow DataContext="{Binding PatientVM}"/>
</ContentControl>
</Window>
PatientWindow.xaml
<UserControl x:Class="PatientAdminTool.View.PatientWindow"
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:vm="clr-namespace:PatientAdminTool.ViewModel"
xmlns:v="clr-namespace:PatientAdminTool.View"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300" >
<UserControl.DataContext>
<vm:PatientSelectorVM/>
</UserControl.DataContext>
<Grid >
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<DockPanel Grid.Row="0" LastChildFill="True" Height="40" Background="#646161" >
<StackPanel DockPanel.Dock="Left" Orientation="Horizontal">
<TextBlock Margin=" 10,5,0,0" HorizontalAlignment="Center" Text="Patients" FontSize="16" TextAlignment="Center" VerticalAlignment="Center" Foreground="#FFFFFF"/>
</StackPanel>
<StackPanel Margin="10,10,0,0" DockPanel.Dock="Right" Background="Transparent" Orientation="Vertical" HorizontalAlignment="Right" VerticalAlignment="Top" Width="50" >
<StackPanel Background="Transparent" Orientation="Horizontal" HorizontalAlignment="Right">
<Button Focusable="False" ToolTip="Close" VerticalAlignment="Center" Background="#646161" BorderThickness="0" BorderBrush="Transparent" Padding="-4" Command="{Binding CloseCommand,Mode=TwoWay}">
<Button.Content>
<Grid Width="45" Height="23">
<TextBlock Foreground="White" Text="r" FontFamily="Marlett" FontSize="20" VerticalAlignment="Center" HorizontalAlignment="Center"/>
</Grid>
</Button.Content>
<Button.Template>
<ControlTemplate TargetType="Button">
<ContentPresenter Content="{TemplateBinding Content}"/>
</ControlTemplate>
</Button.Template>
</Button>
</StackPanel>
</StackPanel>
</DockPanel>
<ContentControl Grid.Row="1" HorizontalAlignment="Stretch" VerticalAlignment="Stretch" >
<v:PatientSelector DataContext="{Binding PatientSelectorVM}" />
</ContentControl>
</Grid>
</UserControl>
Result should be as per the below image
I need to show the child window by using corresponding view model.
I am not getting how to do this?
You can't access UI elements (including windows) in ViewModels directly.
Just make abstraction of the functionality "Open Window". The easiest way is to use interface:
interface IDialogService
{
public void OpenWindow(BaseViewModel windowViewModel);
}
//in viewmodel:
void OpenPatientWindow_CommandExecuted()
{
var patientWindowVM = new PatientWindowViewModel())
patientWindowVM.Parameter = "This way you can pass parameters";
_dialogService.OpenWindow(patientWindowVM);
}
go here for more inspiration: Handling Dialogs in WPF with MVVM
Bind the Content property of ContentPresenter to the PatientVM property of the MainViewModel in MainWindow.xaml and use define a DataTemplate per child view/view model type:
<ContentControl Content="{Binding PatientVM}">
<ContentControl.Resources>
<DataTemplate DataType="local:PatientSelectorVM">
<v:PatientWindow />
</DataTemplate>
<DataTemplate DataType="local:ThirdScreenType">
<v:ThirdScreenView />
</DataTemplate>
</ContentControl.Resources>
</ContentControl>
You then set the PatientVM property of the MainViewModel to a PatientSelectorVM object to display the PatientWindow view and to a ThirdScreenType object (or whatever your class is actually called) to display the other view in the ContentControl.
Make sure that the MainViewModel implements the INotifyPropertyChanged interface and raise the PropertyChanged event in the setter of the PatientVM property:
public BaseViewModel PatientVM
{
get { return _patientVM; }
set
{
patientVM = value;
OnPropertyChanged();
}
}
For you to be able to set the property to both a PatientSelectorVM object and the other type of objects, these classes should derive from the same base class or implement the same interface.

Need help implementing DataTemplate Selector [WP8.1] [WindowsPhone]

I have made a simple RSS Feed app using AppStudio, and as the title suggests, I need some help on implementing DataTemplateSelector.
I want the first and the last items of the feed to use "BigCards" item template, while the others to have the "SmallCards" item template.
Here is the code for the item template styling:
<!-- BigCards Item -->
<DataTemplate x:Key="BigCards">
<Grid Style="{StaticResource BoxGrid}" Margin="0,0,0,10" Height="380">
<Rectangle Width="900"/>
<Grid Style="{StaticResource BoxGrid}">
<Grid.RowDefinitions>
<RowDefinition Height="280"/>
<RowDefinition Height="220"/>
</Grid.RowDefinitions>
<Image Grid.Row="0" Source="{Binding ImageUrl}" Stretch="UniformToFill" Margin="0,4,0,0" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Grid Grid.Row="1" Height="220" Margin="10,10,10,10">
<Grid Height="210">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Style="{StaticResource BoxTitleStyle}" Text="{Binding Title}" MaxLines="2"/>
</Grid>
</Grid>
</Grid>
</Grid>
</DataTemplate>
<!-- SmallCards Item -->
<DataTemplate x:Key="SmallCards">
<Grid Height="120" Margin="0,0,0,10" Style="{StaticResource BoxGrid}">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="120"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Image Source="{Binding ImageUrl}" Stretch="UniformToFill" VerticalAlignment="Center" HorizontalAlignment="Center"/>
<Grid Grid.Column="1">
<Rectangle Width="900" Height="0"/>
<Grid Margin="16,5,16,5">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Style="{StaticResource BoxTitleStyle}" Text="{Binding Title}" MaxLines="2"/>
<TextBlock Grid.Row="1" Margin="0,5,0,0" Style="{StaticResource BoxSubtitleStyle}" Text="{Binding Summary}"/>
</Grid>
</Grid>
</Grid>
Here is some code behind Mainpage.xaml.cs which is needed as a trigger between these item templates:
//Listim dinamik i artikujve
public abstract class TemplateSelector : ContentControl
{
public abstract DataTemplate SelectTemplate(object item, DependencyObject container);
protected override void OnContentChanged(object oldContent, object newContent)
{
base.OnContentChanged(oldContent, newContent);
ContentTemplate = SelectTemplate(newContent, this);
}
}
//endof Abstract Class
public class ArticleTemplateSelector : TemplateSelector
{
public DataTemplate BigCards
{
get;
set;
}
public DataTemplate SmallCards
{
get;
set;
}
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
// Determine which template to return;
return null;
}
}
I would really appreciate if someone could help me on what I should insert in the DataTemplate SelectTemplate class so the first and the last item on my RSS Feed will use BigCards template, while the others will use SmallCards...?
Here is the Main Page xaml which as for the moment uses the BigCards template:
<Hub x:Name="Container" Grid.Row="1" Margin="0,28,0,0" Background="{StaticResource AppBackground}" DataContext="{Binding}" SectionsInViewChanged="OnSectionsInViewChanged">
<HubSection x:Name="LajmetSection" Padding="0,-30,20,0" Width="400" DataContext="{Binding MainViewModel.LajmetModel}"
d:DataContext="{d:DesignData Source=/Assets/Data/LajmetDataSource.json, Type=vm:LajmetViewModel, IsDesignTimeCreatable=true}"
ContentTemplate="{StaticResource BigCards}" IsHeaderInteractive="{Binding HasMoreItems}" />
</Hub>
Regards
I solved it in a different way. I modified the RSS page of my website in a way which would assign a static author for every 10th post. In my case I assigned every 10th post to "X" author. Then I implemented this simple statement
if (RssSchema.Author==X)
use BigCards;
else
use SmallCards;
which does the job quite nicely. If anyone needs help feel free to contact me.

DataTemplate localization using WPFLocalizationExtension

I'm using WPFLocalizationExtension to localize a C#/ .Net4.5 application but I didn't manage to localize DropDown Menus with custom DataTemplate because I can't use the DisplayMemberPath. For ordinary dropdown localization works like this:
<telerik:RadComboBox ItemsSource="{Binding GlassColors}"
SelectedValue="{Binding Ampule.ID_GlassColor, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
SelectedValuePath="ID_GlassColor"
DisplayMemberPath="{lang:Loc dmp_GlassColor}"/>
The ComboBox example above is linked to a database table containing to language. The displayed language is changed by the localized DisplayMemberPath. This approach is very easy and I can recommend it to everyone else. How ever it doesn't work for comboboxes using a custom DataTemplate. See example below:
<telerik:RadComboBox ItemsSource="{Binding PackagingTypesFilter}"
SelectedValue="{Binding SelectedPackagingTypeFilter}"
SelectedValuePath="ID_PackagingType">
<telerik:RadComboBox.ItemTemplate>
<DataTemplate DataType="{x:Type model:Tbl_PackagingMaster_ID_PackagingType}">
<Grid VerticalAlignment="Center" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding TypeIcon, Converter={StaticResource StringToUriConverter}}" VerticalAlignment="Top" Grid.Column="0" Height="14" Margin="2" />
<TextBlock Text="{Binding PackagingTypeDescription}" Style="{StaticResource TextBlockMediumSmallBlackStyle}" Grid.Column="1"/>
</Grid>
</DataTemplate>
</telerik:RadComboBox.ItemTemplate>
</telerik:RadComboBox>
The ItemSource is a Collection where PackagingTypeDescription contains the English and PackagingTypeDescriptionGerman contains the German description.
How can I localize the code sample above?
I solved this using a TemplateSelector.
Here is the TemplateSelector class:
using System.Windows;
using System.Windows.Controls;
namespace Common.TemplateSelector
{
public class LanguageTemplateSelector : DataTemplateSelector
{
public DataTemplate TemplateEnglish { get; set; }
public DataTemplate TemplateGerman { get; set; }
public const string LanguageIdentifier = "de";
public override DataTemplate SelectTemplate(object item, DependencyObject container)
{
return Configuration.Configuration.Language == LanguageIdentifier ? this.TemplateGerman : this.TemplateEnglish;
}
}
}
And here the template definition and the definition of the TemplateSelector defined in the <UserControl.Resources></UserControl.Resources> area:
<DataTemplate DataType="{x:Type model:Tbl_PackagingMaster_ID_PackagingType}" x:Key="PackagingTypeEnglish">
<Grid VerticalAlignment="Center" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding TypeIcon, Converter={StaticResource StringToUriConverter}}" VerticalAlignment="Top" Grid.Column="0" Height="14" Margin="2" />
<TextBlock Text="{Binding PackagingTypeDescription}" Style="{StaticResource TextBlockMediumSmallBlackStyle}" Grid.Column="1"/>
</Grid>
</DataTemplate>
<DataTemplate DataType="{x:Type model:Tbl_PackagingMaster_ID_PackagingType}" x:Key="PackagingTypeGerman">
<Grid VerticalAlignment="Center" HorizontalAlignment="Left">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="24" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Image Source="{Binding TypeIcon, Converter={StaticResource StringToUriConverter}}" VerticalAlignment="Top" Grid.Column="0" Height="14" Margin="2" />
<TextBlock Text="{Binding PackagingTypeDescriptionGerman}" Style="{StaticResource TextBlockMediumSmallBlackStyle}" Grid.Column="1"/>
</Grid>
</DataTemplate>
<templateSelector:LanguageTemplateSelector x:Key="PackagingTypeLanguageSelector"
TemplateEnglish="{StaticResource PackagingTypeEnglish}"
TemplateGerman="{StaticResource PackagingTypeGerman}" />
This is how I use it for the ComboBox:
<telerik:RadComboBox ItemsSource="{Binding PackagingTypesFilter}"
SelectedValue="{Binding SelectedPackagingTypeFilter}"
SelectedValuePath="ID_PackagingType"
ItemTemplateSelector="{StaticResource PackagingTypeLanguageSelector}" />
However, I'm still looking for a more elegant way to solve this.

Proper Code-Behind Object Data Binding in XAML?

I am currently binding an object in my code-behind (C#) to my XAML by giving a name to the XAML control, and setting the DataContext in the code-behind.
public partial class SmsControl: UserControl
{
private readonly DataOrganizer _dataOrganizer;
public FunctionalTester _funcTester;
public SmsControl()
{
InitializeComponent();
_dataOrganizer = new DataOrganizer();
_funcTester = new FunctionalTester();
// Set the datacontext appropriately
grpModemInitialization.DataContext = _funcTester;
}
private async void Button_Click_2(object sender, RoutedEventArgs e)
{
await _funcTester.Test();
}
}
And my XAML...
<!-- SMS Test Modem Initialization GroupBox -->
<GroupBox x:Name="grpModemInitialization" Grid.Column="1" Grid.Row="1" Grid.ColumnSpan="3" Style="{StaticResource groupboxViewItem}">
<GroupBox.Header>
<Label Content="SMS Test Modem Initialization" Style="{StaticResource boldHeaderItem}"/>
</GroupBox.Header>
<!-- SMS Test Modem Initialization Grid -->
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="50"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<Label Grid.Column="0" Grid.Row="0" Grid.RowSpan="2" Content="COM:" Style="{StaticResource boldHeaderItem}" />
<ComboBox Grid.Column="1" Grid.Row="0" Grid.RowSpan="2" Style="{StaticResource comboBoxItem}" ItemsSource="{Binding AvailableCommPorts}" SelectedItem="{Binding SelectedCommPort}" />
<Label Grid.Column="2" Grid.Row="0" Content="Modem Ready:" Style="{StaticResource boldHeaderItem}" />
<Label Grid.Column="2" Grid.Row="1" Content="RSSI:" Style="{StaticResource boldHeaderItem}" />
<Label Content="{Binding ModemReady}" Grid.Column="3" Grid.Row="0" HorizontalContentAlignment="Left" VerticalAlignment="Center"/>
<Label Content="{Binding ModemRssi}" Grid.Column="3" Grid.Row="1" HorizontalContentAlignment="Left" VerticalAlignment="Center" />
<Label Grid.Column="4" Grid.Row="0" Content="Modem #:" Style="{StaticResource boldHeaderItem}"/>
<Button Grid.Column="4" Grid.Row="1" Grid.ColumnSpan="2" Content="Initialize" />
<Label Content="{Binding ModemNumber}" Grid.Column="5" Grid.Row="0" HorizontalContentAlignment="Left" VerticalAlignment="Center"/>
</Grid>
</GroupBox>
The code above works fine - no problems. What I'm asking is, if there is a way to set the DataContext of the GroupBox in XAML, referencing my _funcTester object, instead of setting the DataContext in the code-behind? The reason I ask, is because different controls need to be bound to different objects in the code-behind and I'm not finding good resources on how to do so, except as I show above (giving a "x:Name" to each XAML control and setting the DataContext in code-behind). Any help is appreciated! Thanks!
You don't want to reference UI elements by name in the code-behind. Actually any time you can avoid naming an object you save a little in performance. And by setting up your app to use MVVM properly, you gain in performance, readability, maintainability, and code separation.
You want to abstract things further to use the MVVM pattern. You're doing your bindings correctly but consider the pattern. Your view is all correct. Consider adding a class that holds the properties defined currently in your code-behind and the methods called in your event handlers.
public class ViewModel : INotifyPropertyChanged
{
private FunctionalTester _funcTester;
public FunctionalTester FuncTester
{
get
{
return _funcTester;
}
set
{
_funcTester = value;
OnPropertyChanged( "FuncTester" );
}
}
public async void TestAsync( )
{
await _funcTester.Test( );
}
}
A binding to the FuncTester would simply be SomeProperty="{Binding FuncTester}" because the object is set as the DataContext of your view. A decent article that expands on this idea is found here.
Obviously left out some things (like INotifyPropertyChanged implementation and other properties you've defined) for brevity. But just make this class and assign it as your view model. Then the UI (the Xaml and the code-behind) only really deal with the UI and the ViewModel really deals with the data and logic. Great separation. For your event handler, just call ((ViewModel)this.DataContext).Test( ); and you can plug-and-play your ViewModel's to change functionality on the fly. Hope this helps!
Just set the DataContext of whole UserControl to self i.e do
this.DataContext = this; in constructor.
Then define the Property for _functinTester
public FunctionalTester FuncTester { get {return _funcTester} };
Now in your xaml you can do
<GroupBox x:Name="grpModemInitialization" DataContext="{Binding FuncTester}"/>
In this way since you have the DataContext set for your whole usercontrol, you can bind any control to any property within that DataContext

c# and wpf crisis with blank listbox items

I gave up on my code bugs so I decide to write here. I really hope to get a solution. What I want with the listbox is: when i click the button, it will retrieve data from database then load it into the listbox. It worked fine. But when I add wpf style, it started problem because I want to add image into each item next to text - image (right side) and text (left side). The result in the listbox is blank but actually it seems there is a data list - please look at the picture. I may have done something wrong in my code or wpf. I am not sure what is problem.... I would appreciate if you can have a look at my code. Your given code would be much helpful. Thanks alot!
WPF:
<ListBox Name="lstDinner" DisplayMemberPath="Name" Margin="513,85,608,445" Style="{DynamicResource ResourceKey=styleListBox}"/>
WPF STYLE:
<DataTemplate x:Key="templateListBoxItem">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Margin="0,0,10,0">
<Image Source="{Binding Path=Image}"
Stretch="Fill"
Height="40"
Width="40"></Image>
</Border>
<TextBlock Text="{Binding Path=Name}"
FontWeight="Bold"
Grid.Column="1"
Grid.Row="0"></TextBlock>
<TextBlock Text="{Binding Path=About}"
Grid.Column="1"
Grid.Row="1"></TextBlock>
</Grid>
</DataTemplate>
<Style x:Key="styleListBox" TargetType="{x:Type ListBox}">
<Setter Property="ItemTemplate" Value="{StaticResource ResourceKey=templateListBoxItem}"></Setter>
</Style>
C#:
private void Button_Click(object sender, RoutedEventArgs e)
{
_dinnerExtractor = new DinnerExtractor();
const int oneDay = 1;
_databaseDinnerList = new ObservableCollection<FoodInformation>(_dinnerExtractor.GetDinnerDays(oneDay));
if (_databaseDinnerList != null)
{
foreach (var list in _databaseDinnerList)
{
lstDinner.Items.Add(new FoodInformation { Dinner = list.Dinner, DinnerImage = list.DinnerImage});
}
//lstDinner.ItemsSource = _databaseDinnerList;
}
}
FoodInformation class does not contains properties: Image and Name (you are trying binding to these properties in DataTemplate).
From code-behind we can create definition of FoodInformation class with properties Dinner and DinnerImage:
class FoodInformation
{
public string Dinner { get; set; }
public ImageSource DinnerImage { get; set; }
}
So you should binding to properties Dinner and DinnerImage, not to Image and Name.
If you change in DataTemplate appropriate properties names everything will be ok.
<DataTemplate x:Key="templateListBoxItem">
<Grid Margin="5">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"></ColumnDefinition>
<ColumnDefinition Width="*"></ColumnDefinition>
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition></RowDefinition>
<RowDefinition></RowDefinition>
</Grid.RowDefinitions>
<Border Grid.Column="0"
Grid.Row="0"
Grid.RowSpan="2"
Margin="0,0,10,0">
<Image Source="{Binding Path=DinnerImage }"
Stretch="Fill"
Height="40"
Width="40"></Image>
</Border>
<TextBlock Text="{Binding Path=Dinner }"
FontWeight="Bold"
Grid.Column="1"
Grid.Row="0"></TextBlock>
</Grid>
</DataTemplate>

Categories