Alyanto
asked on
Access properties in nested observable collections
I have a View Model where there are nested Observable Collections.
ViewModelBase
The Contributor Mode which is nested in the deal model
The top level Deal model
The View Model
The Control XAML please assume that DataContext ultimately = Deals and the collection at that level works fine.
This is the mark-up where I am struggling to connect to the sub Observable Collection
I have tried
ViewModelBase
using System;
using System.Collections.Generic;
using System.ComponentModel;
using System.Linq;
using System.Runtime.InteropServices;
using Microsoft.Win32.SafeHandles;
namespace SharedCode
{
public class ViewModelBase : INotifyPropertyChanged, IDisposable
{
//public event PropertyChangedEventHandler PropertyChanged;
public event PropertyChangedEventHandler PropertyChanged;
protected virtual void OnPropertyChanged(string PropertyName)
{
PropertyChangedEventHandler handler = PropertyChanged;
if (handler != null) handler(this, new PropertyChangedEventArgs(PropertyName));
}
protected bool SetProperty<T>(ref T field, T value, string PropertyName)
{
if (EqualityComparer<T>.Default.Equals(field, value))
{
return false;
}
field = value;
OnPropertyChanged(PropertyName);
return true;
}
// Flag: Has Dispose already been called?
bool disposed = false;
// Instantiate a SafeHandle instance.
SafeHandle handle = new SafeFileHandle(IntPtr.Zero, true);
// Public implementation of Dispose pattern callable by consumers.
public void Dispose()
{
Dispose(true);
GC.SuppressFinalize(this);
}
// Protected implementation of Dispose pattern.
protected virtual void Dispose(bool disposing)
{
if (disposed)
return;
if (disposing)
{
handle.Dispose();
// Free any other managed objects here.
//
}
// Free any unmanaged objects here.
//
disposed = true;
}
}
}
The Contributor Mode which is nested in the deal model
using System;
using System.Linq;
using SharedCode;
namespace SAFEPanel.LatestDeal
{
public class ModelDealContributors:ViewModelBase
{
public ModelDealContributors(string contributorname, string imagepath, double contributorpercentage)
{
ContributorName = contributorname;
ContributorPercentage = contributorpercentage;
Uri path = new Uri(imagepath);
ImagePath = path;
}
string contributorName = "";
public string ContributorName
{
get { return contributorName; }
set { SetProperty(ref contributorName, value, "ContributorName"); }
}
Uri imagePath = new Uri("C:\\Sabershare\\images\\NoConsultantImage.jpg");
public Uri ImagePath
{
get { return ImagePath; }
set { SetProperty(ref imagePath, value, "ImagePath"); }
}
double contributorPercentage = 0.0;
public double ContributorPercentage
{
get { return contributorPercentage; }
set { SetProperty(ref contributorPercentage, value, "ContributorPercentage"); }
}
}
}
The top level Deal model
using System;
using System.Collections.ObjectModel;
using System.Linq;
namespace SAFEPanel.LatestDeal
{
public class ModelDealDetails:ViewModelBase
{
public ModelDealDetails()
{
LoadDeals();
}
private ModelDealDetails(string companyname, string candidatename, DateTime startdate, double fees )
{
CompanyName = companyname;
CandidateName = candidatename;
Startdate = startdate;
Fees = fees;
}
public ObservableCollection<ModelDealContributors> Contributors = new ObservableCollection<ModelDealContributors>();
public ObservableCollection<ModelDealDetails> DealDetails = new ObservableCollection<ModelDealDetails>();
string companyName = string.Empty;
public string CompanyName
{
get { return companyName; }
set { SetProperty(ref companyName, value, "CompanyName"); }
}
string candidateName = string.Empty;
public string CandidateName
{
get { return candidateName; }
set { SetProperty(ref candidateName, value, "CandidateName"); }
}
DateTime startDate = DateTime.Now;
public DateTime Startdate
{
get { return startDate; }
set { SetProperty(ref startDate, value, "Startdate"); }
}
double fEes = 0.0;
public double Fees
{
get { return fEes; }
set { SetProperty(ref fEes, value, "Fees"); }
}
void LoadDeals()
{
ModelDealDetails Deal1 = new ModelDealDetails("Safe Computing", "Joe Smith", DateTime.Now, 500.00);
Deal1.Contributors.Add(new ModelDealContributors("Tiny Deol", "C:\\Sabershare\\images\\Amrutha Nukala.jpg", 15));
Deal1.Contributors.Add(new ModelDealContributors("Robert Patchy", "C:\\Sabershare\\images\\Charles Blockley.jpg", 25));
Deal1.Contributors.Add(new ModelDealContributors("Paolo Kuba", "C:\\Sabershare\\images\\Chris Quinlan.jpg", 20));
Deal1.Contributors.Add(new ModelDealContributors("james Smith", "C:\\Sabershare\\images\\George Gibbs.jpg", 40));
DealDetails.Add(Deal1);
ModelDealDetails Deal2 = new ModelDealDetails("Claires Accessories", "Shaun Tully", DateTime.Now, 850.00);
Deal2.Contributors.Add(new ModelDealContributors("Tiny Deol", "C:\\Sabershare\\images\\Amrutha Nukala.jpg", 100));
DealDetails.Add(Deal2);
}
void GetDealData()
{ }
}
}
The View Model
using System;
using System.Collections.ObjectModel;
using System.Linq;
using SAFEPanel.SharedCode;
namespace SAFEPanel.LatestDeal
{
public class ViewModelLatestDeal:ViewModelControl
{
public ViewModelLatestDeal()
{
ModelDealDetails modeldeals = new ModelDealDetails();
Deals = modeldeals.DealDetails;
}
ObservableCollection<ModelDealDetails> deals = new ObservableCollection<ModelDealDetails>();
public ObservableCollection<ModelDealDetails> Deals
{
get { return deals; }
set { SetProperty(ref deals, value, "Deals"); }
}
}
}
The Control XAML please assume that DataContext ultimately = Deals and the collection at that level works fine.
<UserControl x:Class="SAFEPanel.LatestDeal.LatestDeal"
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:xpanels="clr-namespace:SAFEPanel.XPanel"
mc:Ignorable="d" Width="575" Height="239">
<StackPanel>
<ItemsControl ItemsSource="{Binding Deals}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical" Background="AntiqueWhite">
<Border BorderBrush="Black" BorderThickness="2" CornerRadius="3" Margin="0,3,0,0">
<WrapPanel FlowDirection="RightToLeft" Background="Red">
<Grid HorizontalAlignment="Stretch"
VerticalAlignment="Stretch"
Background="AntiqueWhite">
<Grid.ColumnDefinitions>
<ColumnDefinition Width=".4*"/>
<ColumnDefinition Width=".2*"/>
<ColumnDefinition Width=".4*"/>
</Grid.ColumnDefinitions>
<StackPanel Grid.Column="0" Background="Aqua" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Label x:Name="CompanyName"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
Content="{Binding CompanyName}"
Width="130"
Height="32"/>
<Label x:Name="CandidateName"
HorizontalAlignment="Right"
Content="{Binding CandidateName}"
Width="130"
Height="32"/>
<Label x:Name="Startdate"
HorizontalAlignment="Left"
Content="{Binding Startdate}"
Width="130"
Height="32"/>
<Label x:Name="Fees"
HorizontalAlignment="Left"
Content="{Binding Fees}"
Width="130"
Height="32"/>
</StackPanel>
<StackPanel Grid.Column="1"
Background="Green"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Label x:Name="TitleCompanyName"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
Content="Company"
Width="130"
Height="32"/>
<Label x:Name="TitleCandidateName"
HorizontalAlignment="Left"
Content="Candidate"
Width="130"
Height="32"/>
<Label x:Name="TitleStartdate"
HorizontalAlignment="Left"
Content="Start"
Width="130"
Height="32"/>
<Label x:Name="TitleFees"
HorizontalAlignment="Left"
Content="Fees"
Width="130"
Height="32"/>
</StackPanel>
<StackPanel Grid.Column="2"
Background="Purple"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Label x:Name="TitleCompanyName213"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
Content="{Binding Deal.Contributors.ContributorName}"
Width="130"
Height="32"/>
</StackPanel>
</Grid>
</WrapPanel>
</Border>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</UserControl>
This is the mark-up where I am struggling to connect to the sub Observable Collection
<StackPanel Grid.Column="2"
Background="Purple"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch">
<Label x:Name="TitleCompanyName213"
HorizontalAlignment="Left"
HorizontalContentAlignment="Left"
Content="{Binding Deal.Contributors.ContributorName}"
Width="130"
Height="32"/>
</StackPanel>
I have tried
Content="{Binding Deal.Contributors.ContributorName}"
AND
Content="{Binding Path= Contributors.ContributorName}"
AND
ASKER CERTIFIED SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
Yes, because you're binding to the Contributors property of the individual Deal object.
ASKER
I will give it a try in the morning an tell you how I get on with it, many thank
s so far
s so far
SOLUTION
membership
This solution is only available to members.
To access this solution, you must be a member of Experts Exchange.
ASKER
My intent is to award 1% of the reward to me and 99% to you because a small inspiration is great but knowledge is better.
ASKER
Thank you for a great deal of help
Pleased you got it working.
Hadn't even noticed that you had a field and not a property!
Hadn't even noticed that you had a field and not a property!
ASKER