Split items using ItemsControl - c#

This is the XAML:
<ListView.View>
<GridView>
<GridViewColumn DisplayMemberBinding="{Binding Path=ScenarioName}" Header="Scenario Name" />
<GridViewColumn DisplayMemberBinding="{Binding Path=ScenarioType}" Header="Scenario Type" />
<GridViewColumn Header="Well names" Width="175">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=Wells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<!--<TextBlock Text="{Binding}"/>-->
<Button Width="60" Margin="0 0 0 3">Test 1</Button>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn DisplayMemberBinding="{Binding Path=StartPeriod}" Header="Start period" />
<GridViewColumn DisplayMemberBinding="{Binding Path=EndPeriod}" Header="End period" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Lagged}" Header="Lagged" />
<GridViewColumn DisplayMemberBinding="{Binding Path=Detrended}" Header="Detrended" />
<GridViewColumn DisplayMemberBinding="{Binding Path=MinimumMonths}" Header="Length of continuous months" />
<GridViewColumn DisplayMemberBinding="{Binding Path=CorrelatedWells}" Header="Correlated wells" />
<GridViewColumn Header="Excluded Wells">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<ItemsControl ItemsSource="{Binding Path=ExcludedWells}">
<ItemsControl.ItemsPanel>
<ItemsPanelTemplate>
<WrapPanel Orientation="Vertical"/>
</ItemsPanelTemplate>
</ItemsControl.ItemsPanel>
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding}"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
And it looks like:
http://tinypic.com/view.php?pic=xpse8n&s=6
The questions is whether there is an easy to group the "Test1" buttons under Well names(in groups of,let say, 5 items) because the volume of well names can be quite big and neither horizontal nor vertical wrapping helps.
many thanks,
elias

Well you can always add a new property to your ViewModel
public IEnumerable<Well> SomeWells
{ get { return Wells.Take(5); }
and change your ItemsSource binding to use this instead.
Example here on MSDN

You could use a ListBox to let the user scroll through the buttons like:
<GridViewColumn Header="Well names" Width="175">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ListBox>
<ListBox.ItemTemplate>
<DataTemplate>
<Button></Button>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>

I'm not 100% sure of what you're asking, but it sounds like you want something like 5 buttons in a row, and automatically wrapping to the next row every 5 buttons.
To make it work with a WrapPanel, you should give your panel a Width that is 5x with width of your buttons so it will draw 5 of them, then wrap to the next line
<ItemsPanelTemplate>
<WrapPanel Width="300" Orientation="Vertical"/>
</ItemsPanelTemplate>
Another alternative if you don't know your Button width ahead of time is to use a UniformGrid with 5 Columns. I think you also need to set the Row count to something larger than you ever expect your collection to be
<ItemsPanelTemplate>
<UniformGrid Columns="5" Rows="100" />
</ItemsPanelTemplate>
Another alternative for defining the Row count is to expose a property in your data model that contains the number of rows you'll need, and binding the Rows property to it.
<ItemsPanelTemplate>
<UniformGrid Columns="5" Rows="{Binding RowCount}" />
</ItemsPanelTemplate>
I can't remember if UniformGrid.Rows is a DependencyProperty or not, but if not then you can create an AttachedProperty instead that you can bind to and that will modify the UniformGrid.Rows property (for an example, see this code for Attached Properties for a Grid's Rows and Columns)

Related

showing multiple items inside listview

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.

WPF ListView - 2 dimensions with 1 same structure

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.

From Code Retrieve dynamically generated objects from listview's datatemplate

The key here in the title is that I want to retrieve an object, specifically a canvas, that is contained in my listviewitem's datatemplate.
I have an ObservableCollection of ints in the ViewModel property MySimpleData. Associated with each int is a canvas. Essentially I am using a listview to display an array of "pictures". The user can click buttons which changes the contents of the "Canvases". However a single picture object can last many frames so I don't store them in the canvas but rather in a separate location with a start index and a duration. I would like to procedurally generate each of the canvases in my listview. How can I retrieve my canvas for each index?
I am looking for soemthing along the lines of:
MyListView.Items.(Related-DataTemplate).(Related-Canvas)
My goal is to essentially clear all the canvases and re-draw/refresh them when I want. This is a mock up / demo so I don't mind if the solution is a bit hacky. I just need something that works well enough and won't require me to write my own control.
My intent would be to iterate MyListView.items essentially call, related-canvas.clear(); and then for the picture-objects for that canvas I will call related-canvas.addChild(Relevant-Picture-Object);
Here is my xaml in case it helps.
<ListView Name="MyListView"
ItemsSource="{Binding MySimpleData}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn Header="Column1"
DisplayMemberBinding="{Binding}"/>
<GridViewColumn Header="Column2-Canvases"
Width="{Binding DataContext.CanvasWidth, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<Canvas
Width="{Binding DataContext.CanvasWidth, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Height="{Binding DataContext.CanvasHeight, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Background="LightSlateGray"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
Any ideas would are greatly appreciated.
Cheers.
So I ended up replacing the collection with a collection of canvas objects. The next step was to replace the binding and use a content presenter, to directly display the canvases that were in my collection. One other useful change I made was to the column 1 code to display the index of my items. Not as hacky as I was looking for, but arguably hacky enough.
<ListView Name="MyListView"
<!-- COMMENT ItemsSource="{Binding MySimpleData}"> END COMMENT-->
ItemsSource="{Binding CanvasCollection}"> <!-- EDIT HERE -->
AlternationCount="{Binding CanvasCollection.Count}"
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel Orientation="Horizontal"/>
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.View>
<GridView>
<GridView.Columns>
<!-- COMMENT <GridViewColumn Header="Column1"
DisplayMemberBinding="{Binding}"/> END COMMENT -->
<GridViewColumn Header="Index" Width="37">
<GridViewColumn.CellTemplate> <!-- NEW Index displaying code -->
<DataTemplate>
<Label Content="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListViewItem}}, Path=(ItemsControl.AlternationIndex)}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Column2-Canvases"
Width="{Binding DataContext.CanvasWidth, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}" >
<GridViewColumn.CellTemplate>
<DataTemplate>
<!-- COMMENT <Canvas
Width="{Binding DataContext.CanvasWidth, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Height="{Binding DataContext.CanvasHeight, RelativeSource={RelativeSource AncestorType={x:Type UserControl}}}"
Background="LightSlateGray"/> END COMMENT -->
<ContentPresenter Content="{Binding}" /> <!-- NEW -->
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>

Add multiple items in a listbox row

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.

How to bind a Dictionary<enum,bool> property to a GridViewColumn?

I am trying to bind a Dictionary property stored in a EffectViewModel inside an ObservableCollection, but it appears as "(Collection)" in the column I want to see as checkboxes.
Xaml for the GridViewColumn is this:
<GridViewColumn
Width="100"
Header="GPU"
DisplayMemberBinding="{Binding ShaderSupport}">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="0"
HorizontalAlignment="Center"
IsChecked="{Binding Value}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
ShaderSupport is of type Dictionary<ShaderType, bool> where I just want to read in the bool value for ShaderType.GPU for this GridViewColumn.
Any ideas?
EDIT: Using this shows me the bool value as string, so I am in the right path I think:
DisplayMemberBinding="{Binding ShaderSupport[GPU]}">
Try this:
<GridViewColumn
Width="100"
Header="GPU">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox Margin="0"
HorizontalAlignment="Center"
IsChecked="{Binding ShaderSupport[CPU]}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>

Categories