Within a ListView - GridViewColumn change content based on ComboBox Selection - c#

I am struggling trying to understand how I can allow a user to select a value from a combo box in a GridView column and have that selection impact other items within that GridView column (Labels, Textbox, etc). If they simply select an item from the combo box I don't appear to have the selected item / index from the ListView nor do I have the GridViewColumn so I can access its contents...This is most likely user error as I am new to WPF. Any suggestions would be greatly appreciated.
So in the xaml below I want to be able (for example) change the Label content for a given combo box selection. I can detect the combo box selection in code behind, but need to be able to access the other elements in that grid view column.
EDIT: ListView could be the wrong choice to begin with. I tried DataGrid as well, but this seemed to allow more flexibility within the columns for dynamic content.
Xaml:
<Grid x:Name="GridWindows" DockPanel.Dock="Bottom">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>
<ListView x:Name="LvValues" ItemContainerStyle="{StaticResource AlternatingListViewItemStyle}" AlternationCount="2">
<ListBox.Items>
<sys:String>Value1</sys:String>
<sys:String>Value2</sys:String>
<sys:String>Value3</sys:String>
</ListBox.Items>
<ListView.View >
<GridView>
<GridViewColumn Header="Value" Width="120" DisplayMemberBinding="{Binding}" />
<GridViewColumn Header="Terminal" Width="50">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox IsChecked="False"></CheckBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Header="Distribution" Width="400" x:Name="Distribution">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<ComboBox Width="100" x:Name="CbDistribution" SelectedValuePath="Content" SelectionChanged="CbDistribution_OnSelectionChanged">
<ComboBoxItem x:Name="Beta">Beta</ComboBoxItem>
<ComboBoxItem x:Name="Constant">Constant</ComboBoxItem>
<ComboBoxItem x:Name="Gamma">Gamma</ComboBoxItem>
</ComboBox>
<Label x:Name="DistributionArg1" Content="k="></Label>
<Label x:Name="DistributionArg2" Content="Theta="></Label>
<Label x:Name="DistributionArg3" Content="Other="></Label>
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
</Grid>

Related

Slow performance of list view in WPF

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?

How to access checkboxes in a List view one by one

I want to check all text boxes on the basis of if the check box is checked. But I don't know how to access all check boxes one by one? I bound it with ApprovalStatus which is of boolean type. Can any one help me to have code in C#?
<CheckBox Content="Check All" Height="16" HorizontalAlignment="Left" Margin="9,193,0,0" Name="Tab2CheckAll" VerticalAlignment="Top" Width="77" Click="Tab2CheckAll_Click"/>
<ListView Height="213" HorizontalAlignment="Left" Margin="9,215,0,0" Name="Tab2EmployeeEffortList" VerticalAlignment="Top" Width="771" AllowDrop="True" IsTextSearchEnabled="True">
<ListView.View>
<GridView>
<GridViewColumn Header="Approved" Width="100">
<GridViewColumn.CellTemplate>
<DataTemplate>
<CheckBox CommandParameter="{Binding}" IsChecked="{Binding ApprovalStatus}"/>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
You need not to access individual checkBoxes. CheckBox is already bounded to property set that instead.
Loop over ItemsSource of ListView and set ApprovalStatus to true for all items in the collection. As long as your underlying source class is implementing INotifyPropertyChanged, it will work fine.

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.

How to enable/disable TextBox according to ComboBox in ListView

Is it possible to enable/disable TextBox according to ComboBox selected value (for example enable it if selected value is "From To"?
<ListView Height="120" HorizontalAlignment="Left" Margin="19,92,0,0"
VerticalAlignment="Top" Width="500"
SelectionMode="Multiple"
ItemsSource="{Binding Products}">
<ListView.View>
<GridView>
<!--another columns-->
<GridViewColumn Header="Selection Mode">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox Width="70" Name="SelectionMode">
<ComboBoxItem Content="From To" IsSelected="True" />
<ComboBoxItem Content="List" />
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<TextBox Width="70"></TextBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I'd suggest that you use ComboBoxItem's values as opposed to content. You'll need to write a binding which will bind your combobox SelectedValue (see my suggestion) to Enabled of your textbox. The binding will use a converter (IValueConverter), which will return True or False depending on SelectedValue value passed in - based on your query if SelectedValue == 'FromTo', your converter will return True, otherwise False.
I'd also suggest that you use objects, backing your UI elments, which is by all means a cleaner way of doing things.

Checkbox in gridviewcolumn(header)

I am using a listview (gridview/gridviewcolumn)
where the first column
contains only checkboxes for each row. Instead of adding a select all button I want
to add a Checkbox into the header of the first column.
Selecting the checkbox in the header will select
all other checkboxes and vice versa.
How can I do that in xaml?
Update:
This is the important part of my xaml code. (simplified)
<ListView ItemSource="...">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
To have a checkbox on top of GridViewColumn you can do something like this
<GridViewColumn>
<GridViewColumn.Header>
<CheckBox/>
</GridViewColumn.Header>
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<CheckBox IsChecked="{Binding IsSelected}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
Now you can handle the check event and in the code you can iterate through your itemsSource and change values or if you are following MVVM you can bind property with checkbox so that whenever check is changed you will be notified through INotifyPropertyChanged. Once you find out through binding that check has changed, again you can change your itemssource accordingly

Categories