Making listview expandable vertically - wpf

I have divided my xaml page in 3 column. The last column has a list-view and now I'm adding a property grid underneath of it. How can I add a feature on UI such that would allow user to resize the listview or property grid vertically?
I tried but either I'm using wrong attribute or it is not meant for this reason. any help will be appreciated.
<StackPanel Grid.Column="5" Background="gray">
**<ScrollViewer VerticalScrollBarVisibility="Auto" >**
<ListView Background="LightGray" Opacity="1" ForceCursor="False" x:Name="myListView" x:FieldModifier="public" Height="326" >
<ListView.View>
<GridView>
<GridViewColumn Header="Parts List" Width="80"/>
</GridView>
</ListView.View>
</ListView>
**</ScrollViewer>**
<DockPanel>
<Grid>
<wpg:WpfPropertyGrid x:Name="PropertyGrid1"
VerticalAlignment="Stretch" HelpVisible="{Binding ElementName=ShowDescrip, Path=IsChecked}"
ToolbarVisible="{Binding ElementName=ShowToolbar, Path=IsChecked}"
PropertySort="{Binding ElementName=ComboSort, Path=SelectedItem}" />
</Grid>
</DockPanel>
</StackPanel>
Thanks.
Amit

You should probably use a Grid and a GridSplitter.
You can have a look here for a quick example.

Related

how to make ListView nonselectable, width like "*", and use DataTemplate

I am learning to use ListView to list data with multiple columns (i.e. column 1 is filename, column 2 is number of pages, etc.), and encountered several problems:
The code below shows 2 columns, where the column width is specified by <GridViewColumn Width="Auto">. How can I specify the columns to use all available width? I tried to set Width="*" like the one for Grid, but that generates an error.
How to make ListView nonselectable? I saw this post on making ListBox nonselectable, but a similar approach doesn't work for ListView (shown in code).
UPDATE: solved question #2. see code.
Can you show a simple example of a ListView using DataTemplate? I just want to have something like <ListView ItemsSource="{Binding }" ItemTemplate="{StaticResource myTemplate}"/> in the MainWindow, so things stay clean.
(4.ish. i learned the code below from this post. Please let me know if there is a simpler way.)
Thank you!
<ListView HorizontalContentAlignment="Stretch" Grid.Row="0" ItemsSource="{Binding }">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Focusable" Value="False"/> <--- disable selection
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Width="Auto">
<GridViewColumnHeader Content="Filename"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Filename}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="Auto">
<GridViewColumnHeader Content="Pages"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Pages}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView>
I'm not sure if there is any other straight-forward solution (although I'm almost sure there is not any direct way to go). The following solution can be considered as a work-around but it's actually a beautiful one.
You can make the second column (or generally the last column) fill the remaining space by using some Binding to bind the ListView's Columns' Width to the Grid's Columns' Width. Yes we know that only Grid has some features which no other controls have. Here are the detailed steps:
Firstly, we need a Grid having the same number of columns with the ListView. The ListView of course should be placed inside this Grid. By using Grid.ColumnSpan we can make the ListView fill the whole Grid.
Secondly, bind the Width of all the Grid columns to the ActualWidth of the corresponding ListView columns except the last Column. The last column of the Grid should have Width set to * (fill the remaining space).
Lastly, you need some dummy element (such as a Border) put in the last column of the Grid. We need this dummy element to get its ActualWidth, so that we can bind the last ListView column's Width to that ActualWidth. A ColumnDefinition of the Grid also has the property ActualWidth but it is not a dependency property and also it does not have any property changed notifying mechanism (so we cannot use that property).
Now is the working code:
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="{Binding ActualWidth,ElementName=firstCol}"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<!-- the dummy element -->
<Border Grid.Column="1" Name="dummy" Margin="5"></Border>
<ListView HorizontalContentAlignment="Stretch" Grid.ColumnSpan="2"
ItemsSource="{Binding }">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Width="Auto" x:Name="firstCol">
<GridViewColumnHeader Content="Filename"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Filename}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="{Binding ActualWidth, ElementName=dummy}">
<GridViewColumnHeader Content="Pages"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Pages}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView>
</Grid>
Note that your original ListView may be placed in some Grid (you set its Grid.Row="0"). However when using this trick, the ListView should always be placed inside a wrapper Grid and you have to set Grid.Row="0" (although this is set by default) for this wrapper Grid instead. I mean this wrapper Grid will be placed in your original Grid (if any present).
Update: To make it dynamic like as a Grid, you need more dummy elements (we use just 1 dummy Border for the last column in the code above). Each dummy elements will be put in each Grid's column. As I explained, we need this to proxy the ActualWidth of the Grid's column, although ColumnDefinition also has an ActualWidth property but it cannot be used in Binding (does not support any change notification). Here is the code:
<Grid Grid.Row="0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="2*"/>
</Grid.ColumnDefinitions>
<!-- the dummy elements -->
<Border Grid.Column="0" Name="dummy1" Margin="5"></Border>
<Border Grid.Column="1" Name="dummy2" Margin="5"></Border>
<!-- your ListView -->
<ListView HorizontalContentAlignment="Stretch" Grid.ColumnSpan="2"
ItemsSource="{Binding }">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="Focusable" Value="False"/>
</Style>
</ListView.ItemContainerStyle>
<ListView.View>
<GridView>
<GridViewColumn Width="{Binding ActualWidth, ElementName=dummy1}">
<GridViewColumnHeader Content="Filename"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Filename}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="{Binding ActualWidth, ElementName=dummy2}">
<GridViewColumnHeader Content="Pages"/>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=Pages}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListView>
</Grid>

How to set tabindex in dynamic generated textbox inside listView in wpf

We built our user interface from XML definitions (not XAML) but underneath we use a WPF to present the UI. That is at runtime, we create the WPF UI based on our XML definition.
<ListView ItemsSource="{Binding}" Width="400px" IsSynchronizedWithCurrentItem="True" HorizontalAlignment="Left" Name="ListView"
ScrollViewer.VerticalScrollBarVisibility="Disabled" ScrollViewer.HorizontalScrollBarVisibility="Disabled" Grid.ColumnSpan="3"
SelectionChanged="ListView_SelectionChanged" BorderThickness="0" IsTabStop="False">
<ListView.View>
<GridView x:Name="grid">
<GridViewColumn Width="100px">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding Path=ModuleName}" Width="100px" Foreground="Black" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="200px">
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Text="{Binding Path=ModuleUserCount, TargetNullValue=''}" MaxLength="6" Name="txtModuleUserCount" KeyDown="txtModuleUserCount_KeyDown" MinWidth="180" MaxWidth="200" BorderBrush="Gray"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</ListView.View>
</ListView>
I generate 4 module through XML SO UI have four TextBox in these dynamic TextBox tabIndex is not working. I tried KeyboardNavigation.TabNavigation="Cycle" but it's not working. How to make tab navigation work for this layout?
I know its too too late, but I would like to answer. I had the same problem. I tried following way and it resolved my problem: Set:
KeyboardNavigation.TabIndex="10"
or whatever value you require in ListView itself.

ListView / DataGrid with multiple rows in cell

I would like to make same ListView / DataGird like the following:
First: I am not sure if it's a ListView or a DataGrid, how can I know?
Second: How can I do that? (AS you can see, there's Icon in the first cell, and the second one is splitted to 3 rows > Name of device, Driver of device and Status of device. The third cell with the volume meter doesnt metter).
Thank you very much!
You can do this with a ListView, ListBox or DataGrid, as there are no headers a ListBox might be easiest.
Just create a ItemTemplate with a Grid, use SharedSizeGroups to make the columns the same size, in the second column add another Grid with three rows for the text.
A ListView in combination with a GridView however would provide columns already, so you just need to create a Grid in the second column, you could style the headers to be collapsed.
<ListView.Resources>
<Style TargetType="{x:Type GridViewColumnHeader}">
<Setter Property="Visibility" Value="Collapsed"/>
</Style>
</ListView.Resources>
GridView example (used as ListView.View):
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Image Width="64" Height="64" Source="{Binding Icon}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition />
<RowDefinition />
<RowDefinition />
</Grid.RowDefinitions>
<TextBlock Grid.Row="0" Text="{Binding Name}" />
<TextBlock Grid.Row="1" Text="{Binding Manufacturer}" Foreground="Gray" />
<TextBlock Grid.Row="2" Text="{Binding Status}" Foreground="Gray" />
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
Thanks to H.B., If you just want to display without selection etc, use an ItemsControl:
ItemsControl

Make WPF ComboBoxes fill a whole column width

I'm having problems making a ComboBox stretch to fill the whole column width in a GridViewColumn. It should also resize when the column is resized.
In the following example I have a StackPanel with a ComboBox inside. This is set to stretch and will in fact stretch to fill the StackPanel width.
Then I add a ListView with one column, containing a StackPanel with a ComboBox. Both the StackPanel and the ComboBox are set to stretch, but they don't. I use background colors to identify the size of the StackPanels, and there is no red unless I set a width or add elements to the ComboBox such that it needs more width.
I also tried playing around with the HorizontalContentAlignment property without success.
<StackPanel Height="59" Margin="45,12,38,0" VerticalAlignment="Top" Background="Green">
<ComboBox HorizontalAlignment="Stretch" />
</StackPanel>
<ListView x:Name="MyListView" Margin="0,106,0,0">
<ListView.View>
<GridView>
<GridViewColumn Header="Num" Width="70">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Background="red" Orientation="Horizontal" HorizontalAlignment="Stretch">
<ComboBox HorizontalAlignment="Stretch" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListViewItem></ListViewItem>
</ListView>
Try setting the Style of the ListViewItem. I also removed your StackPanel.
<ListView x:Name="MyListView" Margin="0,106,0,0">
<ListView.Resources>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"/>
</Style>
</ListView.Resources>
<ListView.View>
<GridView>
<GridViewColumn Header="Num" Width="170">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
<ListViewItem></ListViewItem>
</ListView>

Populate ComboBox in GridView header with column data

I want to have a ComboBox in the header cells of my GridView (currently inside of a ListView) populated with the data from that column. To be used a bit like the 'auto filter' feature in Excel.
The problem I have is I can't get to the data for the column from inside the header cell. At the moment, I have something like this:
<Grid>
<Grid.Resources>
<DataTemplate x:Key="headerTemplate">
<StackPanel>
<ComboBox></ComboBox>
<TextBlock FontSize="16" Text="{Binding}" Grid.Row="1" HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Grid.Resources>
<ListView Width="400" Height="200">
<ListView.View>
<GridView ColumnHeaderTemplate="{StaticResource headerTemplate}">
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding Name}"/>
<GridViewColumn Header="Namespace" DisplayMemberBinding="{Binding Namespace}"/>
</GridView>
</ListView.View>
<x:Type TypeName="Visual"/>
<x:Type TypeName="UIElement"/>
<x:Type TypeName="FrameworkElement"/>
</ListView>
</Grid>
But I'm not sure how to get the data to populate the combo boxes in the header. What's the best way of doing this?
A quick and dirty way would be something like this:
<Grid.Resources>
<DataTemplate x:Key="headerTemplate">
<StackPanel>
<ComboBox ItemsSource="{Binding Path=Items, RelativeSource={RelativeSource Mode=FindAncestor, AncestorType={x:Type ListView}}}" DisplayMemberPath="{Binding}"/>
<TextBlock FontSize="16" Text="{Binding}" Grid.Row="1" HorizontalAlignment="Center"/>
</StackPanel>
</DataTemplate>
</Grid.Resources>
If you really need a filter-like list, you'll have to figure out how to get distinct values only.

Resources