none
Help using Expander with a Listbox using a object class...

    Question

  • Hi,

    I have four object classes defined with each having a ObservableCollection class:

    [Serializable()]
    public class ReferenceContentState : NotificationObject
    {
    	.
    	..
    	...
    	private string percentageText;
    	public string PercentageText
    	{
    		get { return this.percentageText; }
    		set { this.percentageText = value; RaisePropertyChanged(() => this.PercentageText); }
    	}
    
    	private ObservableCollection<ReferenceWritingsState> referenceWritingsOfState;
    	public ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState 
    	{
    		get { return this.referenceWritingsOfState; }
    		set { this.referenceWritingsOfState = value; RaisePropertyChanged(() => this.ReferenceWritingsOfState); }
    	}
    }


    [Serializable()]
    public class ReferenceWritingsState : NotificationObject
    {
    	.
    	..
    	...
    	private string percentageText;
    	public string PercentageText
    	{
    		get { return this.percentageText; }
    		set { this.percentageText = value; RaisePropertyChanged(() => this.PercentageText); }
    	}
    
    	private ObservableCollection<ReferenceChapterState> referenceChapterOfState;
    	public ObservableCollection<ReferenceChapterState> ReferenceChapterOfState
    	{
    		get { return this.referenceChapterOfState; }
    		set { this.referenceChapterOfState = value; RaisePropertyChanged(() => this.ReferenceChapterOfState); }
    	}
    }


    [Serializable()]
    public class ReferenceChapterState : NotificationObject
    {
    	.
    	..
    	...
    	private string percentageText;
    	public string PercentageText
    	{
    		get { return this.percentageText; }
    		set { this.percentageText = value; RaisePropertyChanged(() => this.PercentageText); }
    	}
    
    	private ObservableCollection<ReferenceVerseState> referenceVerseState;
    	public ObservableCollection<ReferenceVerseState> ReferenceVerseState
    	{
    		get { return this.referenceVerseState; }
    		set { this.referenceVerseState = value; RaisePropertyChanged(() => this.ReferenceVerseState); }
    	}
    }


    [Serializable()]
    public class ReferenceVerseState : NotificationObject
    {
    	.
    	..
    	...
    	private string percentageText;
    	public string PercentageText
    	{
    		get { return this.percentageText; }
    		set { this.percentageText = value; RaisePropertyChanged(() => this.PercentageText); }
    	}
    }


    The data is an .xml file and my goal is to have a Listbox display each ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState which is the top level object class in a Expander:

    Initially it display each ReferenceWritingsState correctly.  However when I select one item to expand all items expand:

    And in addition the Listbox scrollbar doesn't activate.  This is the Listbox template:

    <Grid Grid.Row="2" VerticalAlignment="Stretch">
    	<Grid.ColumnDefinitions>
    		<ColumnDefinition MinWidth="200"/>
    		<ColumnDefinition/>
    	</Grid.ColumnDefinitions>
    
    	<GroupBox Header="CREATE WRITINGS">
    		<ListBox >
    			<ListBox.Resources>
    
    				<Style TargetType="{x:Type Expander}">
    					<Setter
    						   Property="IsExpanded"
    						   Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
    				</Style>
    			</ListBox.Resources>
    			<ListBox.Template>
    				<ControlTemplate TargetType="{x:Type ListBox}">
    					<ItemsPresenter/>
    				</ControlTemplate>
    			</ListBox.Template>
    			<ListBox.ItemContainerStyle>
    				<Style TargetType="{x:Type ListBoxItem}">
    					<Setter Property="Template">
    						<Setter.Value>
    							<ControlTemplate TargetType="{x:Type ListBoxItem}">
    								<ContentPresenter Content="{TemplateBinding Content}"/>
    							</ControlTemplate>
    						</Setter.Value>
    					</Setter>
    				</Style>
    			</ListBox.ItemContainerStyle>
    			<HeaderedItemsControl
    				VerticalAlignment="Stretch"
    				ItemTemplate="{StaticResource WritingsContentStateTemplate}"
    				ItemsSource="{Binding Path=odsDocumentsService.WritingsContentState}">
    			</HeaderedItemsControl>
    
    		</ListBox>
    	</GroupBox>
    	
    	...
    	..
    	.
    
    </Grid>

    As you can see I'm using a HeaderedItemsControl to display the data items and using a few HierarchicalDataTemplate to display each ObservableCollection items defined in the UserControl.Resources:

    Displayed in order as defined:

    <Style TargetType="HeaderedItemsControl">
    	<Setter Property="Template">
    		<Setter.Value>
    			<ControlTemplate TargetType="{x:Type HeaderedItemsControl}">
    				<StackPanel>
    					<ContentPresenter ContentSource="Header"/>
    					<ItemsPresenter Margin="10,0,0,0" />
    				</StackPanel>
    			</ControlTemplate>
    		</Setter.Value>
    	</Setter>
    </Style>


    <HierarchicalDataTemplate x:Key="VerseContentStateTemplate">
    
    	<Grid>
    
    		<Grid.ColumnDefinitions>
    			<ColumnDefinition MinWidth="200"/>
    		</Grid.ColumnDefinitions>
    
    		<StackPanel Margin="5 10 5 0">
    			<StackPanel>
    				<DockPanel>
    					<AccessText Text="{Binding Path=Msg}" />
    				</DockPanel>
    				<DockPanel>
    					<TextBlock Text="{Binding Path=PercentageText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    					<ProgressBar Height="25" IsIndeterminate="False" Value="{Binding Path=Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    				</DockPanel>
    			</StackPanel>
    		</StackPanel>
    
    	</Grid>
    </HierarchicalDataTemplate>


    <HierarchicalDataTemplate x:Key="ReferenceChapterOfStateTemplate">
    
    	<Grid>
    
    		<Grid.ColumnDefinitions>
    			<ColumnDefinition MinWidth="200"/>
    		</Grid.ColumnDefinitions>
    
    		<StackPanel Margin="5 10 5 0">
    			<StackPanel>
    				<DockPanel>
    					<TextBlock Text="Writings of "/>
    					<AccessText Text="{Binding Path=Title}" />
    				</DockPanel>
    				<DockPanel>
    					<TextBlock Text="Total Verses "/>
    					<AccessText Text="{Binding Path=Records}" />
    				</DockPanel>
    				<DockPanel>
    					<TextBlock Text="Actions "/>
    					<AccessText Text="{Binding Path=Msg}" />
    				</DockPanel>
    				<DockPanel>
    					<TextBlock Text="{Binding Path=PercentageText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    					<ProgressBar Height="25" IsIndeterminate="False" Value="{Binding Path=Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    				</DockPanel>
    			</StackPanel>
    		</StackPanel>
    
    	</Grid>
    </HierarchicalDataTemplate>

    This is the one using the Expander for ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState displayed in the images above.

    <HierarchicalDataTemplate x:Key="ReferenceWritingsOfStateTemplate">
    
    	<Expander Header="{Binding Path=Title}">
    		<Grid>
    
    			<Grid.ColumnDefinitions>
    				<ColumnDefinition MinWidth="200"/>
    			</Grid.ColumnDefinitions>
    
    			<GroupBox Header="{Binding Path=Hebrew}">
    				<StackPanel Margin="5 10 5 0">
    					<StackPanel>
    						<DockPanel>
    							<TextBlock Text="Writings of "/>
    							<AccessText Text="{Binding Path=Title}" />
    						</DockPanel>
    						<DockPanel>
    							<TextBlock Text="Total Chapter "/>
    							<AccessText Text="{Binding Path=Records}" />
    						</DockPanel>
    						<DockPanel>
    							<TextBlock Text="Actions "/>
    							<AccessText Text="{Binding Path=Msg}" />
    						</DockPanel>
    						<DockPanel>
    							<TextBlock Text="{Binding Path=PercentageText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    							<ProgressBar Height="25" IsIndeterminate="False" Value="{Binding Path=Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    						</DockPanel>
    						<DockPanel>
    							<ScrollViewer VerticalScrollBarVisibility="Auto" Height="200">
    								
    							<HeaderedItemsControl
    							ItemTemplate="{StaticResource ReferenceChapterOfStateTemplate}"
    							ItemsSource="{Binding Path=ReferenceChapterOfState}"
    							Margin="10,0,0,0" />
    							</ScrollViewer>
    						</DockPanel>
    					</StackPanel>
    				</StackPanel>
    			</GroupBox>
    
    		</Grid>
    	</Expander>
    
    </HierarchicalDataTemplate>


    <HierarchicalDataTemplate x:Key="WritingsContentStateTemplate">
    
    	<Grid  VerticalAlignment="Stretch">
    
    			<StackPanel Margin="5 10 5 0" VerticalAlignment="Stretch">
    				<StackPanel VerticalAlignment="Stretch">
    					<DockPanel>
    						<TextBlock Text="Creating Writings of "/>
    						<AccessText Text="{Binding Path=Title}" />
    					</DockPanel>
    					<DockPanel>
    						<TextBlock Text="Total Writings "/>
    						<AccessText Text="{Binding Path=Records}" />
    					</DockPanel>
    					<DockPanel>
    						<TextBlock Text="Actions "/>
    						<AccessText Text="{Binding Path=Msg}" />
    					</DockPanel>
    					<DockPanel>
    						<TextBlock Text="{Binding Path=PercentageText, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    						<ProgressBar Height="25" IsIndeterminate="False" Value="{Binding Path=Percentage, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"/>
    					</DockPanel>
    						<DockPanel>
    							<HeaderedItemsControl
    							ItemTemplate="{StaticResource ReferenceWritingsOfStateTemplate}"
    							ItemsSource="{Binding Path=ReferenceWritingsOfState}"
    							Margin="10,0,0,0" />
    						</DockPanel>
    				</StackPanel>
    			</StackPanel>
    
    	</Grid>
    </HierarchicalDataTemplate>


    Where do I and how do I properly define the IsExpanded for this to work right:

    <Style TargetType="{x:Type Expander}">
    	<Setter
    	   Property="IsExpanded"
    	   Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
    </Style>

    or is there a better approach to what I'm trying to accomplish and if possible an example project I can download?


    Code is like a box of chocolates!...





    • Edited by VcDeveloper Wednesday, September 18, 2013 7:43 AM typo
    Wednesday, September 18, 2013 7:29 AM

Answers

  • I got my ListBox working with the exclusive Expander now!  I had to define a property in my ViewModel that would return the ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState.

    XAML:

    <GroupBox Grid.Column="1" Header="CREATE WRITINGS">
    	<ListBox 
    		Name="dirListBox" 
    		ItemTemplate="{StaticResource ReferenceWritingsOfStateTemplate}"
    		ItemsSource="{Binding Path=ReferenceWritingsOfState}"
    		HorizontalAlignment="Stretch"
    		VerticalAlignment="Stretch"
    		VirtualizingStackPanel.IsVirtualizing="False"
    		VirtualizingStackPanel.VirtualizationMode="Standard">
    		<ListBox.Resources>
    
    			<Style TargetType="{x:Type Expander}">
    				<Setter
    				   Property="IsExpanded"
    				   Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
    			</Style>
    		</ListBox.Resources>
    	</ListBox>
    </GroupBox>
    

    ViewModel:

    private ObservableCollection<ReferenceWritingsState> referenceWritingsOfState;
    public ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState
    {
    	get 
    	{
    		ReferenceContentState referenceContentState = null;
    		if(this.odsDocumentsService.WritingsContentState.Count > 0)
    			referenceContentState = this.odsDocumentsService.WritingsContentState[0] as ReferenceContentState;
    
    		return referenceContentState.ReferenceWritingsOfState;
    	}
    }
    

    Results:

    everything else remains the same as in the first posting.  Now just a few cosmetics and more testing with more data.


    Code is like a box of chocolates!...



    • Marked as answer by VcDeveloper Friday, September 20, 2013 9:10 PM
    • Edited by VcDeveloper Friday, September 20, 2013 9:14 PM format
    Friday, September 20, 2013 9:02 PM

All replies

  • Well, I have it almost working the way I want it too using a TreeView except for the exclusive Expanding:

    <GroupBox Header="CREATE WRITINGS">
    	<TreeView 
    		Name="dirTree" 
    		ItemTemplate="{StaticResource WritingsContentStateTemplate}"
    		ItemsSource="{Binding Path=odsDocumentsService.WritingsContentState}"
    		HorizontalAlignment="Stretch"
    		VerticalAlignment="Stretch"
    		VirtualizingStackPanel.IsVirtualizing="False"
    		VirtualizingStackPanel.VirtualizationMode="Standard">
    	</TreeView>
    </GroupBox>
    



    Code is like a box of chocolates!...

    Thursday, September 19, 2013 5:47 AM
  • Thanks for sharing your solution and search result here. It will help others who are

    interest in this.




    • Edited by Mercop002 Thursday, September 19, 2013 6:21 AM
    Thursday, September 19, 2013 6:20 AM
  • You are welcome! :) 

    Code is like a box of chocolates!...

    Friday, September 20, 2013 12:13 AM
  • I tried the ListBox again and found out why when I select the Expander all the items expand.  Its was treating my template as one item:

    How do I get my ListBox to point to the ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState:

    [Serializable()]
    public class ReferenceContentState : NotificationObject
    {
    
    	private ObservableCollection<ReferenceWritingsState> referenceWritingsOfState;
    	public ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState 
    	{
    		get { return this.referenceWritingsOfState; }
    		set { this.referenceWritingsOfState = value; RaisePropertyChanged(() => this.ReferenceWritingsOfState); }
    	}
    }
    
    because these are the Items I want listed individually.  This object class just holds the overall statistics.


    Code is like a box of chocolates!...


    • Edited by VcDeveloper Friday, September 20, 2013 8:19 PM addional info
    Friday, September 20, 2013 8:06 PM
  • I got my ListBox working with the exclusive Expander now!  I had to define a property in my ViewModel that would return the ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState.

    XAML:

    <GroupBox Grid.Column="1" Header="CREATE WRITINGS">
    	<ListBox 
    		Name="dirListBox" 
    		ItemTemplate="{StaticResource ReferenceWritingsOfStateTemplate}"
    		ItemsSource="{Binding Path=ReferenceWritingsOfState}"
    		HorizontalAlignment="Stretch"
    		VerticalAlignment="Stretch"
    		VirtualizingStackPanel.IsVirtualizing="False"
    		VirtualizingStackPanel.VirtualizationMode="Standard">
    		<ListBox.Resources>
    
    			<Style TargetType="{x:Type Expander}">
    				<Setter
    				   Property="IsExpanded"
    				   Value="{Binding Path=IsSelected, RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}}"/>
    			</Style>
    		</ListBox.Resources>
    	</ListBox>
    </GroupBox>
    

    ViewModel:

    private ObservableCollection<ReferenceWritingsState> referenceWritingsOfState;
    public ObservableCollection<ReferenceWritingsState> ReferenceWritingsOfState
    {
    	get 
    	{
    		ReferenceContentState referenceContentState = null;
    		if(this.odsDocumentsService.WritingsContentState.Count > 0)
    			referenceContentState = this.odsDocumentsService.WritingsContentState[0] as ReferenceContentState;
    
    		return referenceContentState.ReferenceWritingsOfState;
    	}
    }
    

    Results:

    everything else remains the same as in the first posting.  Now just a few cosmetics and more testing with more data.


    Code is like a box of chocolates!...



    • Marked as answer by VcDeveloper Friday, September 20, 2013 9:10 PM
    • Edited by VcDeveloper Friday, September 20, 2013 9:14 PM format
    Friday, September 20, 2013 9:02 PM