WPF ListView selected item visible - wpf

I have a ListView that has its ItemsSource on binding with an ObservableCollection.
<ListView
Name="ShapesList"
ItemsSource="{Binding ChartViewModel.ShapeList}"
Grid.Row="1"
Margin="10,0,10,5"
SelectionMode="Multiple">
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}, Path=DataContext.IsChecked, Mode=TwoWay}" Content="{Binding Path=Name, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type ListViewItem}}}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="PdC" DisplayMemberBinding="{Binding Name}" />
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
This window has a model responsible of the logic: it calculates the checked item of the ListView. What I need is that when the window is open, the checked item of the ListView is visible.
I tried with
ShapesList.ScrollIntoView(ChartViewModel.GetIndexOfSelectedROI());
but it doesn't work, even if the method returns the correct index.
Thanks in advance for any help!

According to MSDN ListView.ScrollInToView takes the object you want to make visible as its parameter, not the index.

Related

Putting ComboBox in a one special row in ListView in WPF

How to put a Combobox to a special row of a listview (WPF, VB.net)?
There is a ListView that has two columns. The columns are "Parameter" and "Values". The second column has different types (such as numbers, strings and "Selectable values") and is editable. The "Selectable values" have to appear in a Combobox.
One of the ways that I think about, is conditional XAML tags (I don`t know if it is possible or not ?) .
I tried this code but it shows Combobox for all rows in listview :
<ListView x:Name="listView"
HorizontalAlignment="Left"
Height="237"
Margin="40,34,0,0"
VerticalAlignment="Top"
Width="447"
ItemsSource="{Binding Values}">
<ListView.View>
<GridView>
<GridViewColumn Header="Parameter"
DisplayMemberBinding="{Binding Path=LName}"
Width="100" />
<GridViewColumn Header="Value"
Width="150">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource AncestorType=ListView}, Path=ItemsSource}"
Width="120">
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Type}" />
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I only want to use Combobox for one row while the type of the rest of rows are double or string. How can I do this?

mvvm ComboBox selection in Listview

I am trying to display a collection of objects in a wpf-Listview and provide a combobox for selection of values from an other collection.
Some code to illustrate my problem:
XAML: (Window gets its DataContext set in app.xaml.cs)
<ListView ItemsSource="{Binding Path=Books}" SelectedItem="{Binding Path=CurrentBook}">
<ListView.View>
<GridView>
<GridViewColumn Header="author" DisplayMemberBinding="{Binding author}" />
<GridViewColumn Header="title" DisplayMemberBinding="{Binding title}" />
<GridViewColumn Header="genre">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Genres}" IsSynchronizedWithCurrentItem="true" DisplayMemberPath="genreName" SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CurrentBook_Genre}">
<ComboBox.ItemTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding genreName}" />
<TextBlock Text="{Binding genreDescription}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
For now is "CurrentBook_Genre" a Property of the MainWindowViewModel, the according value of the Item shown in the ListView is set by its setter.
Like that the same ComboBox is shown in every "row" of the ListView.
I guess I need some kind of "EditValueTemplate" and "ShowValueTemplate" and a Selector of some kind, it would be fine, if the ComboBox gets shown only in the row which is in edit-mode - i guess this is a common thing for most DataDriven apps, so maybe there is a way more easy iam not aware of.
The only good explanation for this was
http://tech.pro/tutorial/857/wpf-tutorial-using-the-listview-part-3-in-place-edit
But they are working with dependency-properties, opposed to the ViewModel-wrapped models iam using.
There is a much easier way to get one control displayed when a grid row is edited and another when it is not edited than the example that you found. Try this instead:
<DataGrid ItemsSource="{Binding Books}" AutoGenerateColumns="False">
<DataGrid.Columns>
<DataGridTemplateColumn>
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CurrentBook_Genre.genreName}" />
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
<DataGridTemplateColumn.CellEditingTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.Genres}" IsSynchronizedWithCurrentItem="true" DisplayMemberPath="genreName" SelectedItem="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type Window}}, Path=DataContext.CurrentBook_Genre}" />
</DataTemplate>
</DataGridTemplateColumn.CellEditingTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
This will display a ComboBox when the row is being edited and a plain old TextBlock when it is not.

Treeview shows random extra space

I have a treeview in wpf that is showing some strange behavior (at least I think it's strange). I don't see anywhere I can attach an image but basically on some of the items it looks like it's double spaced or has an extra 3px or so margin and on some it looks like it's single spaced. Here is the XAML defining it:
<TreeView Margin="5,0,0,5" ItemsSource="{Binding SortedCategories}" HorizontalContentAlignment="Stretch">
<TreeView.Resources>
<HierarchicalDataTemplate DataType="{x:Type COBie:CategoryData}" ItemsSource="{Binding SortedTypes}">
<CheckBox IsChecked="{Binding AnyChecked, Mode=TwoWay}" Content="{Binding CategoryName}" IsEnabled="{Binding HasTypes}" />
</HierarchicalDataTemplate>
<DataTemplate DataType="{x:Type COBie:InstanceData}">
<CheckBox IsChecked="{Binding isChecked, Mode=TwoWay}" Content="{Binding ElemID}" />
</DataTemplate>
<DataTemplate DataType="{x:Type COBie:TypeData}">
<TreeViewItem IsEnabled="{Binding HasInstances}" HorizontalContentAlignment="Stretch">
<TreeViewItem.Header>
<CheckBox IsChecked="{Binding isChecked, Mode=TwoWay}" Content="{Binding ElemName}" />
</TreeViewItem.Header>
<ListView ItemsSource="{Binding SortedInstances}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="{Binding isChecked, Mode=TwoWay}" />
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="ID" DisplayMemberBinding="{Binding ElemID}" />
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding ElemName}" />
<GridViewColumn Header="Mark" DisplayMemberBinding="{Binding Mark}" />
<GridViewColumn Header="Room" DisplayMemberBinding="{Binding RoomDisplay}" />
</GridView>
</ListView.View>
</ListView>
</TreeViewItem>
</DataTemplate>
</TreeView.Resources>
</TreeView>
The only other relevant style that would apply is:
<Style TargetType="TreeViewItem">
<Setter Property="IsExpanded" Value="{Binding IsExpanded}" />
</Style>
I don't see anywhere that defines a margin at all and even if it did all of the elements are of the same class so it should apply to all equally.
Anyone know what is going on?
I had the same issue, that there were seemingly random gaps.
After looking closer I found out that the gaps appeared around items, that have underscore(s) in the name.
If you put the string directly in the content property of the CheckBox and it contains underscores, the CheckBox will surround a TextBlock with a Control named AccessText, probably to support short cut keys (similar to underscores in Button's Content property).
Now for some reason the Margin of the Checkbox is set on the TextBlock perfectly fine, if there is no AccessText involved, but is not set on the TextBlock inside the AccessText. This way the TextBlock inside the AccessText will have default TextBlock Style, which in my case was with Margin=5.
I guess in your case it must be a closely related issue.

CheckBox state of a CellTemplate in ListView

i am trying to use styles to prevent from repeting code, by putting them in a Resource Disctionary.
My question is, when we have a GridViewColumn in a ListView, which one of the columns have a DataTemplate, and in that DataTemplate we have the CellTemplate with only a CheckBox, can we bind the CheckBox state when the DataTemplete is in a ResourceDictionary?
What i have is this in my XAML:
<ListView Name="listView">
<ListView.View>
<GridView AllowsColumnReorder="False">
<GridViewColumn DisplayMemberPath="{Binding [1]}"/>
<GridViewColumn DisplayMemberPath="{Binding [2]}"/>
<GridViewColumn DisplayMemberPath="{Binding [4]}"/>
<GridViewColumn DisplayMemberPath="{Binding [5]}"/>
<GridViewColumn DisplayMemberPath="{Binding [6]}"/>
<GridViewColumn DisplayMemberPath="{Binding [7]}"/>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsThreeState="False" IsChecked="{Binding [8]}" Unchecked="CheckBox_Changed" Checked="CheckBox_Changed"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
And i am trying to do something like this in the Resource Dictionary:
<DataTemplate x:Key="ListViewCheckboxCell">
<StackPanel>
<CheckBox IsThreeState="False" IsChecked="Make reference"/>
</StackPanel>
</DataTemplate>
And the values in that column is always a bool.
Thanks in advance!
What you did seems correct. You'll now have to write
<GridViewColumn CellTemplate="{StaticResource ListViewCheckboxCell}" />
The template will be taken into account, you can leave exactly the same template than the original in your resource dictionary: The binding is dynamically resolved, so when the XAML will be read, bindings will automatically be set to the related object, following what you indicated

WPF - Binding to control using relative path Self.Sibling.Child

Below is the XAML i currently have. I want to emulate a tree by having a toggle button and a listview will bind it's visibility to the toggle buttons chcked state. Problem is, I need to bind to a child of a sibling. Is this even possible?
this code doesn't work becuase the toggle isn't an ancestor.
<StackPanel Orientation="Vertical">
<StackPanel Orientation="Horizontal">
<ToggleButton Name="tglBtn">+</ToggleButton>
<TextBlock>test</TextBlock>
</StackPanel>
<ListView Visibility="{Binding RelativeSource={RelativeSource AncestorType={x:Type ToggleButton}}, Path=IsChecked, Converter={StaticResource boolToVis}}">
<ListView.View>
<GridView>
<GridViewColumn Header="Thread" DisplayMemberBinding="{Binding thread_name}" />
<GridViewColumn Width="Auto" Header="Created" DisplayMemberBinding="{Binding thread_created}" />
<GridViewColumn Width="Auto" Header="Modified" DisplayMemberBinding="{Binding last_modified}" />
</GridView>
</ListView.View>
</ListView>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You can use ElementName Binding to access the ToggleButton
I've found a solution to this problem that is reusable in Styles (it does not require using the ElementName). I've written up the full answer, with examples and screenshots here.

Resources