I am trying to display groups(#'s) and the students who are in that group. I have two listview boxes on a page(wpf). The first listview box displays the group #. And the second listview box displays the first and lastnames of the group that i have selected in the 1st listview. I'm using observableCollection and binding through xaml. Can anybody tell me how I can display the students in the 2nd listview box depending on the group# i have selected in the first listview?
For example:
Listview(group#) box1: contains group numbers 1-20
Listview(names) box2: contains group firstname and lastname
So if i select group number 1(item1) in listview box1, then in listview box2, it should display the first and lastnames that are in that group#
Any help or advice is greatly appreciated. :)
<ListView HorizontalAlignment="Stretch" Margin="0,12" x:Name ="listViewGroups" ItemsSource="{Binding Groups}" DisplayMemberPath="bindMe" IsSynchronizedWithCurrentItem="{x:Null}" Grid.Column="1">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding GroupNumber}" Width="40">
<GridViewColumnHeader Tag="GroupNumber" Content="#" Click="SortClick" />
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding GroupLeader}" Width="120">
<GridViewColumnHeader Tag="GroupLeader" Content="Group Leader" Click="SortClick" />
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding GroupSize}" Width="70">
<GridViewColumnHeader Tag="GroupSize" Content="Group Size" Click="SortClick" />
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<Label Content="Leader" Height="28" Margin="12,12,0,0" Name="lblFirstName" Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Left" />
<TextBox Text="{Binding SelectedItem.GroupLeader, ElementName =listViewGroups}" Height="23" Margin="12,31,0,0" Name="txtFirstName" MaxWidth="160" Grid.Column="2" VerticalAlignment="Top" HorizontalAlignment="Left" Width="160" />
<Label Content="Group Members" Height="28" HorizontalAlignment="Left" Margin="14,60,0,0" Name="label1" VerticalAlignment="Top" Grid.Column="2" />
<ListView HorizontalAlignment="Stretch" Margin="12,80,188,12" x:Name ="listViewGroupMembers" ItemsSource="{Binding Groups}" IsSynchronizedWithCurrentItem="{x:Null}" VerticalAlignment="Stretch" Grid.Column="2">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding path SelectedItem.FirstName, ElementName= listViewGroups}" Width="100">
<GridViewColumnHeader Tag="Name" Content="First Name" Click="SortClick" />
</GridViewColumn>
</Listview>
I am Asumming that you have a Object Group and an Object Student
So your first ListView has ObservableCollection<Groups> and Each Group has a List of Students ObservableColection<Student> so in Xaml You can bind and Write in this way
<ListView Name="GroupList" ItemSource={Binding Path=GroupList}>
</ListView>
<ListView Name="StudentList" ItemSource={Binding Path=SelectedItem.StudentList,ElementName=GroupList}>
</ListView>
This you help you... ;)
Related
Ok so I've been looking for a WPF listview that works something like a treeview. I have a Data Model that has an observerableCollection of children of the item. I've looked at a few options using a few treeview with columns controls that have been shown on stackoverflow or on CodeProject but they either aren't bindable or are too slow to be useful.
The list will be update constantly throughout the day any may have more than 50k-100k items in it by the end of the day. A normal listview control seems to be able to handle these updates and still be useful without completely freezing when a resort is needed.
Now, my data objects should really only ever have one layer of children. So what I was thinking about trying is displaying a toggle button on the listview item (if the item has children), but then when the toggle button is clicked I want to display another listview of that item's children within the current listviewitem. I've been searching for more than a week trying to figure out how to do this. Can anyone lead me in the right direction here? I'm thinking I need a ItemTemplate for the listview but I'm not exactly sure how to get the child listview to show in the parent's listviewitem.
Thanks in advance
UPDATE:
Here is a sample of the XAML I'm currently trying to use but it doesn't seem to be working correctly. I want the columns but when I click the toggle button I want the sub listview to be displayed. Currently all I see is the columns and I can't get the sub listview to display.
<ListView ItemsSource="{Binding MyCollection, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}" x:Name="lsvMyList">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<ListView ItemsSource="{Binding Children}">
<ListView.View>
<GridView>
<GridViewColumn Header="Column2"
DisplayMemberBinding="{Binding Column2}"
Width="100"/>
<GridViewColumn Header="Column3"
DisplayMemberBinding="{Binding Column3}"
Width="100"/>
<GridViewColumn Header="Column5"
DisplayMemberBinding="{Binding Column5}"
Width="100"/>
<GridViewColumn Header="Column8"
DisplayMemberBinding="{Binding Column8}"/>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
<ListView.View>
<GridView>
<GridViewColumn Width="68" Header="IsExpanded">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ToggleButton Visibility="{Binding ChildCount, Converter={StaticResource Toggle}}"
x:Name="tbnItemExpander"
Content="+"
Height="15"
Width="15"
BorderThickness="0"
Background="Transparent"
IsChecked="{Binding IsExpanded, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged, Mode=TwoWay}"
HorizontalContentAlignment="Center"
VerticalContentAlignment="Center"
Click="Toggle_Click"/>
<TextBlock VerticalAlignment="Center"
Text="{Binding ChildCount, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged, Converter={StaticResource RejectCount2}}"
Margin="2,0,2,0"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Column2"
DisplayMemberBinding="{Binding Column2, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}"
Width="63"/>
<GridViewColumn Header="Column3"
DisplayMemberBinding="{Binding Column2, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}"
Width="28"/>
<GridViewColumn Header="Column4"
DisplayMemberBinding="{Binding Column2, NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}"
Width="68"/>
<GridViewColumn Header=""
Width="110">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Click="Button_Click"
Margin="2" Padding="2"
IsEnabled="{Binding Column5, Converter={StaticResource IsNull}}"
Content="{Binding Converter={StaticResource btnContent}}"
Tag="{Binding NotifyOnSourceUpdated=True, NotifyOnTargetUpdated=True, UpdateSourceTrigger=PropertyChanged}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
How do I insert a horizontal line after each list view item in a grid?
<Grid>
<ListView Margin="10" Name="Users">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" Width="300">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" TextTrimming="WordEllipsis" Height="32" Text="{Binding Name}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Age" Width="200">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock TextWrapping="Wrap" TextTrimming="WordEllipsis" Height="32" Text="{Binding Age}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>
I tried defining Border after DataTemplate
<DataTemplate>
<Border Margin="5" BorderThickness="1" BorderBrush="SteelBlue">
but that only added a border around each of the data template items. How do I insert a horizontal separator after each row?
I think you ought to be able to set a row style via the ItemContainerStyle:
https://stackoverflow.com/a/4474474/424129
You'd want to set a BorderThickness="0,0,0,1" to have only a bottom border.
How to create Check box for Column inside Listview. i was able to make checkbox for listview items. but i want to have checkbox for Column itself.like in windows:
here is code in XAML
<ListView HorizontalAlignment="Left" Grid.Row="1" Width="400">
<ListView.View>
<GridView>
<GridViewColumn Width="140" Header="Column1 With Checkbox">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Tag="{Binding}" IsThreeState="False" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="140" Header="Column2" />
<GridViewColumn Width="115" Header="Column3" />
</GridView>
</ListView.View>
</ListView>
Note that this will only make checkboxes for items not Column itself. so how to make this happen?
You can make the header a custom control by defining it under the GridViewColumn.Header property.
<ListView HorizontalAlignment="Left" Grid.Row="1" Width="400">
<ListView.View>
<GridView>
<GridViewColumn Width="140">
<GridViewColumn.Header>
<StackPanel Orientation="Horizontal">
<Checkbox IsChecked="{Binding YourCheckedProperty}" />
<TextBlock Text="Column1" />
</StackPanel>
<GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn Width="140" Header="Column2" />
<GridViewColumn Width="115" Header="Column3" />
</GridView>
</ListView.View>
</ListView>
There probably was a topic in which lays the solution for my problem but I've spend too much hours on this so I've decided to ask.
I have a ListView to which I've binded a collection of processes. And I have a ListBox in which I want to place Threads of a selected process. Binding in ListView works, but analogical in ListBox doesn't.
Here's my .xaml:
<Window x:Class="TaskManager.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Window" Height="453" Width="533" Icon="/TaskManager;component/Images/taskmgr.png">
<Grid>
<ListView Height="276" HorizontalAlignment="Left" Name="processesView" VerticalAlignment="Top" Width="503" ItemsSource="{Binding ProcessList}">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn DisplayMemberBinding="{Binding ProcessName}">
<GridViewColumn.Header>
<GridViewColumnHeader Click="nameColumnHeader_Click">
Name
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Id}">
<GridViewColumn.Header>
<GridViewColumnHeader Click="IDColumnHeader_Click">
ID
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding BasePriority}">
<GridViewColumn.Header>
<GridViewColumnHeader Click="priorityColumnHeader_Click">
Priority
</GridViewColumnHeader>
</GridViewColumn.Header>
</GridViewColumn>
<GridViewColumn Header="Keep alive">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox x:Name="keepAliveBox" IsChecked="{Binding EnableRaisingEvents}" Checked="keepAliveBox_Checked" Unchecked="keepAliveBox_Unchecked" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
<ListBox Height="120" HorizontalAlignment="Left" Margin="93,282,0,0" Name="threadBox" VerticalAlignment="Top" Width="200" ItemsSource="{Binding ElementName=processesView, Path=SelectedItem.Threads}">
<ListBox.ItemTemplate>
<DataTemplate>
<!--<ListBoxItem Content="{Binding}"/>-->
<Label Content="{Binding Name}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</Grid>
After execution I can't see anything in the ListBox but if I click inside something is selected. So if I change the above to Content="TEST" I can see several Labels with "TEST" value. So it seems that I'm binding the name somehow incorrectly.
Here's the .cs part where I set the context:
public MainWindow()
{
InitializeComponent();
processesView.DataContext = this;
threadBox.DataContext = this;
...
}
Items were invisible but selectable so it was probable that I was binding the wrong thing. And that's the reason. I was binding to Name property of Thread whilst Process has a collection of ProcessThreads which don't have that property. Here's the fix in .xaml:
<ListBox Height="120" HorizontalAlignment="Left" Margin="93,282,0,0" Name="threadBox" VerticalAlignment="Top" Width="200" ItemsSource="{Binding ElementName=processesView, Path=SelectedItem.Threads}">
<ListBox.ItemTemplate>
<DataTemplate>
<Label Content="{Binding Path=Id}" />
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
Can't wait for XAML debugger in Visual Studio 2015.
I have a collection of items where the last column is a collection with a celltemplate of it's own.
The ListView's item source is set dynamically in code and all of the other columns are rendering correctly. However, the final column's data is not being read at all. I've tried different solutions from other questions, but they don't seem to work for me.
<Window x:Class="bbowl.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:diag="clr-namespace:System.Diagnostics;assembly=WindowsBase"
Title="Blood Bowl Data" Height="350" Width="525">
<Window.Resources>
<DataTemplate x:Key="SkillTemplate">
<TextBlock Text="{Binding Path=name}" ToolTip="{Binding Path=description}" Height="18" HorizontalAlignment="Left" VerticalAlignment="Top" Foreground="Blue"><TextBlock.TextDecorations><TextDecoration /></TextBlock.TextDecorations></TextBlock>
</DataTemplate>
<DataTemplate x:Key="SkillsTemplate">
<DataGrid AutoGenerateColumns="False" Height="Auto" HorizontalAlignment="Left" VerticalAlignment="Top" HeadersVisibility="None" HorizontalScrollBarVisibility="Hidden" ItemsSource="{Binding Path=Skills}" BorderThickness="0" ItemTemplate="{StaticResource SkillTemplate}" />
</DataTemplate>
</Window.Resources>
<Grid>
<ComboBox HorizontalAlignment="Left" Name="cbxRace" VerticalAlignment="Top" Width="503" Height="25" SelectionChanged="cbxRace_SelectionChanged" ItemsSource="{Binding}" />
<Label Content="Rerolls:" Height="25" HorizontalAlignment="Left" Margin="0,25,0,0" Name="lblRerollLabel" VerticalAlignment="Top" Width="435" HorizontalContentAlignment="Right" FontWeight="Bold" />
<Label Content="0" Height="25" HorizontalAlignment="Left" Margin="441,25,0,0" Name="lblReroll" VerticalAlignment="Top" Width="62" HorizontalContentAlignment="Right" />
<ListView Height="263" HorizontalAlignment="Left" Margin="0,48,0,0" Name="lvwPlayer" VerticalAlignment="Top" Width="503" ItemsSource="{Binding}">
<ListView.View>
<GridView>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Path=name}"/>
<GridViewColumn Header="MA" DisplayMemberBinding="{Binding Path=ma}" />
<GridViewColumn Header="ST" DisplayMemberBinding="{Binding Path=st}" />
<GridViewColumn Header="AG" DisplayMemberBinding="{Binding Path=ag}" />
<GridViewColumn Header="Max" DisplayMemberBinding="{Binding Path=max}" />
<GridViewColumn Header="Price" DisplayMemberBinding="{Binding Path=price}" />
<GridViewColumn Header="Skills" CellTemplate="{StaticResource SkillsTemplate}"/>
</GridView>
</ListView.View>
</ListView>
</Grid>
</Window>
To solve your problem you would need to change your SkillsTemplate to something like this:
<DataTemplate x:Key="SkillsTemplate">
<DataGrid
AutoGenerateColumns="False"
HorizontalAlignment="Left"
VerticalAlignment="Top"
HeadersVisibility="None"
ItemsSource="{Binding Path=Skills}"
BorderThickness="0"
GridLinesVisibility="None">
<DataGrid.Columns>
<DataGridTemplateColumn CellTemplate="{StaticResource SkillTemplate}"/>
</DataGrid.Columns>
</DataGrid>
</DataTemplate>
which instead of changing whole items template creates one column that displays your text using SkillTemplate. However, as far I can see, for what you want to do with it you may consider using less complicated control like ListBox or even ItemsControl when you just want to display bunch of items without giving user option to select one
<DataTemplate x:Key="SkillsTemplate">
<ItemsControl ItemsSource="{Binding Path=Skills}" ItemTemplate="{StaticResource SkillTemplate}"/>
</DataTemplate>