We are working on a ListView (C# WPF) and we didn't found how bind a list of items in columns, with each item containing itself a list of items with the same columns.
Let's illustre this in an example :
!
We got an observable collection on objects with parameters (name, etc.) and each object contain another observable collection of objects with the sames parameters (exept they haven't a list). So we want to list it in a ListView but we can't figure how !
We do not know enough ListView to implement this structure, some advices ?
Thanks in advance
I think the best way is :
XAML :
<Window.Resources>
<DataTemplate x:Key="gridViewSecondCellTemplate1">
<StackPanel Width="100">
<TextBlock Text="{Binding Content}" FontSize="15" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="gridViewCellTemplate1">
<StackPanel Width="100">
<TextBlock Text="{Binding Title}" FontSize="15" />
<ListView ItemsSource="{Binding MySecondSource}>
<ListView.View>
<GridView>
<GridViewColumn Header="{Binding Subtitle}" CellTemplate="{StaticResource gridViewSecondCellTemplate1}"/>
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</DataTemplate>
</Window.Resources>
<ListView ItemsSource="{Binding MySource}">
<ListView.View>
<GridView>
<GridViewColumn Header="Col 1" Width="100" CellTemplate="{StaticResource gridViewCellTemplate1}"/>
</GridView>
</ListView.View>
</ListView>
I didn't try this code. Try it, and say me if it is OK.
Related
I have a list view with a ton of data and any time I go to scroll / click somewhere on the screen it always takes a few seconds to react. I tried setting the list view to use virtualization but can't seem to get it to work.
I have tried this and this. Not sure if I am doing something wrong or not understanding how the virtualization works?
I do have a lot of styling / added grid view behaviors for my listview. If you have any suggestions please let me know!
What I Have Tried
I have tried removing the CollapseableCollumnBehavior from the list view. Had no change.
Removed all my font styles. Had no change.
Reduced the number of columns. Had a small change but still very unresponsive.
Turned off IsSyncronizedWithCurrentItem. Had no change.
Item Source
My item source is just an observable collection.This is how I load data into it.
private void LoadAllData()
{
using (var uow = _unitOfWorkFactory.Create())
{
foreach (var rule in _ruleRepository.GetAllRulesInCheckProcess())
{
AllRulesInCheckProcess.Add(rule);
}
}
}
XAML:
I took out a lot of my styling and added column behaviors from the xaml to simplify the code.
<ListView SelectedValue="{Binding SelectedRule}"
IsSynchronizedWithCurrentItem="True"
Grid.Column="0"
MinHeight="150"
VirtualizingStackPanel.IsVirtualizing="True"
VirtualizingStackPanel.VirtualizationMode="Recycling"
ScrollViewer.IsDeferredScrollingEnabled="True"
ItemsSource="{Binding AllRulesInCheckProcess}"
MaxHeight="300"
ScrollViewer.HorizontalScrollBarVisibility="Visible">
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Description}" Width="auto">
<GridViewColumnHeader Content="Description">
<GridViewColumnHeader.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBox Height="25"
FontSize="{StaticResource FontSizeSmall}"
Text="{Binding ElementName=RulesInCheckProgressPage, Path=DataContext.DescriptionFilter}"
Tag="Filter Description"/>
<TextBlock Text="Description"/>
</StackPanel>
</DataTemplate>
</GridViewColumnHeader.ContentTemplate>
</GridViewColumnHeader>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding LaunchDate,StringFormat=MM/dd/yy}"
Width="auto">
<GridViewColumnHeader Content="Launch Date">
<GridViewColumnHeader.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBox Height="25"
FontSize="{StaticResource FontSizeSmall}"
Tag="Filter Launch Date"
Text="{Binding ElementName=RulesInCheckProgressPage, Path=DataContext.LaunchDateFilter}"/>
<TextBlock Text="Launch Date"/>
</StackPanel>
</DataTemplate>
</GridViewColumnHeader.ContentTemplate>
</GridViewColumnHeader>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding AddedDate,StringFormat=MM/dd/yy}" Width="auto">
<GridViewColumnHeader Content="Added Date">
<GridViewColumnHeader.ContentTemplate>
<DataTemplate>
<StackPanel>
<TextBox Height="25"
FontSize="{StaticResource FontSizeSmall}" Tag="Filter Added Date"
Text="{Binding ElementName=RulesInCheckProgressPage, Path=DataContext.AddedDateFilter}"/>
<TextBlock Text="Added Date"/>
</StackPanel>
</DataTemplate>
</GridViewColumnHeader.ContentTemplate>
</GridViewColumnHeader>
</GridViewColumn>
</GridView>
</ListView.View>
UPDATE
So through doing some more research it appears I may need to take a look at data virtualization instead of UI virtualization. Does anyone know of any up to date data virtualization code?
I was wondering if there is a way to show multiple elements inside listview.view.
SampleCode (which doesnst work)
<ListView
x:Name="Somename"
ItemsSource="{Binding someObservableCollection}">
<ListView.View>
<TextBlock></TextBlock>
<TextBlock></TextBlock>
<TextBlock></TextBlock>
<GridView>
<GridViewColumn Header="Column 1" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Column 2">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock></TextBlock>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Sample Data properties for a person.
Name
Age
Id
OldData1
OldData2
OldData3
NewData1
NewData2
NewData3
I am trying to show Name, age, Id and 3 textblocks
and then in a grid, compare olddata vs new data.
I tried doing with itemtemplate and then doing stackpanel with grid inside, but that grid looks very basic and would prefer gridview since it looks better.
I have 2 ObservableCollection lists, which we can call A and B, then I have a GridView that I want to bind to list A and a ComboBox INSIDE that GridView, that I want to bind to list B.
I've set the ItemsSource property of the GridView by code: gridview.ItemsSource=A (and it works!). About the ComboBox its instance it is not available by code, I suppose because its definition it is enclosed between the DataTemplate tags; so I wonder how to bind the combo to list B, either by code or by XAML.
Follows the XAML code:
<ListView Grid.Row="0" Grid.Column="1" HorizontalAlignment="Stretch" Margin="0,0,0,0" Name="lstReplacements" VerticalAlignment="Stretch">
<ListView.View>
<GridView>
<GridViewColumn HeaderContainerStyle="{StaticResource MyHeaderStyle}" Header="Wrong text" DisplayMemberBinding="{Binding Word}"/>
<GridViewColumn HeaderContainerStyle="{StaticResource MyHeaderStyle}" Header="Replacement" Width="60" DisplayMemberBinding="{Binding Replacement}" />
<GridViewColumn HeaderContainerStyle="{StaticResource MyHeaderStyle}" Header="Type" Width="30">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{??????}" DisplayMemberPath="??????" Grid.Row="1" Grid.Column="0" Name="cmbCorrectionType" Width="75" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
Thanks in advance for the support!
Chris
I assume this control is in UserControl and you have set DataContext of that UserControl to the class instance where your both collections CollectionA and CollectionB resides.
You can then bind using RelativeSource:
<ComboBox ItemsSource="{Binding DataContext.CollectionB,
RelativeSource={RelativeSource Mode=FindAncestor,
AncestorType=UserControl}}"/>
Also you can set DataContext of ListView to the class instance and all you need to do is change AncestorType to ListView in place of UserControl in above binding.
So far i have been working with listview without any problem. I have been able to pass multiple columns and fill them with images, text etc. I decided to do the same thing with a listbox but things there got complicated.
In a listview i do the following :
<DataTemplate x:Key="ImageTemplate" >
<Image x:Name="FavoriteImageList" Tag="{Binding tagger}" Width="12" Height="12" Source="{Binding ImageSource}" MouseLeftButtonDown="FavoriteImageList_MouseLeftButtonDown"/>
</DataTemplate>
<ListView x:Name="Citys">
<ListView.View>
<GridView ColumnHeaderContainerStyle="{StaticResource myHeaderStyle}">
<GridViewColumn Width="90" Header="Image" CellTemplate="{StaticResource ImageTemplate}"/>
<GridViewColumn Width="178" Header="Name" DisplayMemberBinding="{Binding Name}" />
<GridViewColumn Width="178" Header="City" DisplayMemberBinding="{Binding City}"/>
<GridViewColumn Width="140" Header="Author" DisplayMemberBinding="{Binding Author}"/>
</GridView>
</ListView.View>
</ListView>
And i fill columns like this :
foreach(var fav in Favorites)
{
Citys = new List<ACity>()
{
new ACity() {tagger = Name ,ImageSource = ImageSource ,Name= Name, Author= Author, City = City}
};
ListBox.Items.Add(Citys);
}
If I do this in a listbox, it will fill with (Collection).
Is there a way to do this in a listbox, passing images buttons strings in a listbox row?
See the example from the MSDN ItemsControl.ItemTemplate
<ListBox Width="400" Margin="10"
ItemsSource="{Binding Source={StaticResource myTodoList}}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Path=TaskName}" />
<TextBlock Text="{Binding Path=Description}"/>
<TextBlock Text="{Binding Path=Priority}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
It should be pretty straight forward to match with your example.
I'm gonna create a ListView in WPF like the below image
(source: picfront.org)
http://www.picfront.org/d/7xuv
I mean I wanna add an image beside of Gravatar label within Name column.
Would it be OK if you guided me ?
Edit:
The image is output of a method. The method makes the image from a base-64 string.
As long as you're already familiar with how to data bind a ListView then it's pretty simple really. In your cell template you would just need a StackPanel with an Image and a TextBlock side by side.
<ListView>
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Image Width="16" Height="16" Source="{Binding IconUri}"/>
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn ... />
<GridViewColumn ... />
</GridView>
</ListView.View>
</ListView>