New to wpf and therefore struggling a bit.
I am putting together a quick demo before we go for the full implementation
I have a treeview on the left with
Continent
Country
City structure
when a user select the city it should populate some textboxes in a tabcontrol on the right hand side
I made it sort of work but cannot make it work with composite objects.
In a nutshell can you spot what is wrong with my zaml or code.
Why is not binding to a my CityDetails.ClubsCount or CityDetails.PubsCount?
What I am building is based on http://www.codeproject.com/KB/WPF/TreeViewWithViewModel.aspx
Thanks a lot for any suggestions or reply
DataModel
public class City
{
public City(string cityName)
{
CityName = cityName;
}
public string CityName { get; set; }
public string Population { get; set; }
public string Area { get; set; }
public CityDetails CityDetailsInfo { get; set; }
}
public class CityDetails
{
public CityDetails(int pubsCount,int clubsCount)
{
PubsCount = pubsCount;
ClubsCount = clubsCount;
}
public int ClubsCount { get; set; }
public int PubsCount { get; set; }
}
ViewModel
public class CityViewModel : TreeViewItemViewModel
{
private City _city;
private RelayCommand _testCommand;
public CityViewModel(City city, CountryViewModel countryViewModel):base(countryViewModel,false)
{
_city = city;
}
public string CityName
{
get { return _city.CityName; }
}
public string Area
{
get { return _city.Area; }
}
public string Population
{
get { return _city.Population; }
}
public City City
{
get { return _city; }
set { _city = value; }
}
public CityDetails CityDetailsInfo
{
get { return _city.CityDetailsInfo; }
set { _city.CityDetailsInfo = value; }
}
}
XAML
<DockPanel>
<DockPanel LastChildFill="True">
<Label DockPanel.Dock="top" Content="Title " HorizontalAlignment="Center"></Label>
<StatusBar DockPanel.Dock="Bottom">
<StatusBarItem Content="Status Bar" ></StatusBarItem>
</StatusBar>
<Grid DockPanel.Dock="Top">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<TreeView Name="tree" ItemsSource="{Binding Continents}">
<TreeView.ItemContainerStyle>
<Style TargetType="{x:Type TreeViewItem}">
<Setter Property="IsExpanded" Value="{Binding IsExpanded,Mode=TwoWay}"/>
<Setter Property="IsSelected" Value="{Binding IsSelected,Mode=TwoWay}"/>
<Setter Property="FontWeight" Value="Normal"/>
<Style.Triggers>
<Trigger Property="IsSelected" Value="True">
<Setter Property="FontWeight" Value="Bold"></Setter>
</Trigger>
</Style.Triggers>
</Style>
</TreeView.ItemContainerStyle>
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type ViewModels:ContinentViewModel}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="3,0" Source="Images\Continent.png"/>
<TextBlock Text="{Binding ContinentName}"/>
</StackPanel>
</HierarchicalDataTemplate>
<HierarchicalDataTemplate DataType="{x:Type ViewModels:CountryViewModel}"
ItemsSource="{Binding Children}">
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="3,0" Source="Images\Country.png"/>
<TextBlock Text="{Binding CountryName}"/>
</StackPanel>
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type ViewModels:CityViewModel}" >
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Margin="3,0" Source="Images\City.png"/>
<TextBlock Text="{Binding CityName}"/>
</StackPanel>
</DataTemplate>
</TreeView.Resources>
</TreeView>
<GridSplitter Grid.Row="0" Grid.Column="1" Background="LightGray"
Width="5" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"/>
<Grid Grid.Column="2" Margin="5" >
<TabControl>
<TabItem Header="Details" DataContext="{Binding Path=SelectedItem.City, ElementName=tree, Mode=OneWay}">
<StackPanel >
<TextBlock VerticalAlignment="Center" FontSize="12" Text="{Binding CityName}"/>
<TextBlock VerticalAlignment="Center" FontSize="12" Text="{Binding Area}"/>
<TextBlock VerticalAlignment="Center" FontSize="12" Text="{Binding Population}"/>
<!-- DONT WORK WHY-->
<TextBlock VerticalAlignment="Center" FontSize="12" Text="{Binding SelectedItem.CityDetailsInfo.ClubsCount}"/>
<TextBlock VerticalAlignment="Center" FontSize="12" Text="{Binding SelectedItem.CityDetailsInfo.PubsCount}"/>
</StackPanel>
</TabItem>
</TabControl>
</Grid>
</Grid>
</DockPanel>
</DockPanel>
Look here (irrelevant bits elided):
The DataContext for the TabItem is the SelectedItem.City: that is, the DataContext is a City. City doesn’t have a SelectedItem property. Change your bindings to e.g.
i.e. start the path from the current DataContext, in this case the City object.
As a tip, the Visual Studio Output window displays binding errors, which can often provide sufficient information to diagnose this immediately e.g. if you see “Property ‘SelectedItem’ not found on ‘City'” it’s clear that WPF isn’t looking at the object you think it’s looking at!