I have a nested ListView, but the ItemSource binding is never firing. Am I missing something in here? Here you can see my parent list view, which is binding just fine. But the nested one does not.
<ListView ItemsSource="{Binding Items}">
<ListView.View>
<GridView>
<GridViewColumn>
<GridViewColumn.CellTemplate>
<DataTemplate>
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="25"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<CheckBox IsChecked="True" Margin="0,0,5,0"></CheckBox>
<TextBlock Text="{Binding Name}" Margin="0,0,15,0"/>
<TextBlock Text="Task Set Loop: "/>
<TextBox Text="{Binding Scenarios}"/>
</StackPanel>
<ListView Grid.Row="1" ItemsSource="{Binding ChildItems, Converter={StaticResource DebugBindingConverter}}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal" Grid.Row="0">
<CheckBox IsChecked="True" Margin="0,0,5,0"></CheckBox>
<TextBlock Text="{Binding Name}" Margin="0,0,15,0"/>
<ComboBox SelectedItem="{Binding DependentTaskName}"/>
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</Grid>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
My binding for the ChildItems was at the wrong level. Changed that line to:
<ListView Grid.Row="1" ItemsSource="{Binding Path=DataContext.ChildItems, RelativeSource={RelativeSource FindAncestor, AncestorType={x:Type UserControl}}}">
For UWP we can get it like this
<GridView x:Name="abc" ItemsSource="{Binding Path=DataContext.Companies,RelativeSource={RelativeSource Mode=TemplatedParent}}"></GridView>
Related
I am working on wpf and using an ItemsControl to represent a list of class on the UI.
My code is like this:
<ItemsControl ItemsSource="{Binding Path=UsecaseListItems}" >
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<CheckBox IsChecked="{Binding Path=IsSelected,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay,IsAsync=True}"
Margin="2,5"/>
<Button Content="{Binding UsecaseName}"
Margin="2,5"/>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
Now I wand to add a header to both the columns (Select all and UseName) at the top of the list. How can I do it??
Below is the solution (Not a good one but I supposed worse design are also possible) and please change bindings in your code:
XAML:
<ItemsControl ItemsSource="{Binding Path=list}" >
<ItemsControl.Template>
<ControlTemplate>
<StackPanel Orientation="Vertical">
<Border BorderThickness="5" BorderBrush="DarkGray">
<StackPanel Orientation="Horizontal">
<Button Content="Select All" Width="80" HorizontalAlignment="Stretch"/>
<Button Content="User name" Width="80" HorizontalAlignment="Stretch"/>
</StackPanel>
</Border>
<Border BorderThickness="5" BorderBrush="LightGray">
<ItemsControl ItemsSource="{Binding RelativeSource={RelativeSource Mode=TemplatedParent},Path=ItemsSource}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<WrapPanel>
<CheckBox IsChecked="{Binding Path=DeviceState,UpdateSourceTrigger=PropertyChanged, Mode=TwoWay,IsAsync=True}"
HorizontalAlignment="Stretch" Width="100" Margin="2,5"/>
<Button Content="{Binding Name}" HorizontalAlignment="Stretch" Width="100" Margin="2,5"/>
</WrapPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Border>
</StackPanel>
</ControlTemplate>
</ItemsControl.Template>
</ItemsControl>
Output
Why do you want buttons as header? can't you just put buttons outside the ItemsControl?
It is preferable to go with ListView control instead of ItemsControl for what you need.
Here is the sample. .
<Grid>
<Grid.Resources>
<DataTemplate x:Key="checkboxHeaderTemplate">
<CheckBox Checked="CheckBox_Checked"> //add command for MVVM
</CheckBox>
</DataTemplate>
<DataTemplate x:Key="CheckBoxCell">
<CheckBox IsChecked="{Binding Path=IsSelected, Mode=TwoWay}" >
</CheckBox>
</DataTemplate>
<DataTemplate x:Key="ButtonCell">
<Button Content="{Binding Path=UsecaseName, Mode=TwoWay}" >
</Button>
</DataTemplate>
</Grid.Resources>
<ListView ItemsSource="{Binding Path=UsecaseListItems}" >
<ListView.View>
<GridView>
<GridView.Columns>
<GridViewColumn HeaderTemplate="{StaticResource checkboxHeaderTemplate}"
CellTemplate="{StaticResource CheckBoxCell}" Width="auto">
</GridViewColumn>
<GridViewColumn HeaderTemplate="{StaticResource checkboxHeaderTemplate}"
CellTemplate="{StaticResource ButtonCell}" Width="auto">
</GridViewColumn>
</GridView.Columns>
</GridView>
</ListView.View>
</ListView>
</Grid>
Hope that helps.
I have an object hierarchy of this: Orders have Allocations. My DataGrid has an ItemSource of Orders which then shows some details of each order in each grid row. Upon clicking on a grid row, a details pane comes up with additional details including a list of Allocations for each order. What I need to do is to somehow reference back to the Master record and pull a bit of detail (which would end up repeating) for each allocation. If I try to RelativeSource back to the DataGrid, I cannot refer to the property since that source is a whole collection and I need to get the value off of the item of that collection.
Below is a simplified version of the XAML I'm using. Basically, I need to bind to QuantityTypeDescription that's in the master record from each Allocation item in the child (Order) record.
<DataGrid ItemsSource="{Binding Orders}" AutoGenerateColumns="False" IsReadOnly="True" HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="Trade" Binding="{Binding TransactionTypeDescription}" Width="*"/>
<DataGridTextColumn Header="Adjustment" Binding="{Binding QuantityTypeDescription}" Width="Auto"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<!--Order Summary-->
<StackPanel Orientation="Vertical">
<StackPanel Background="DarkSlateGray" Orientation="Vertical">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding TransactionTypeDescription}" FontWeight="Bold" Margin="5,0,0,0" FontSize="14" Foreground="White"/>
</StackPanel>
<TextBlock Name="Name" Text="{Binding SecurityName}" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" Background="DarkSlateGray"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{Binding Allocations}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
NOTE: Here I need to get back up one level to get QuantityTypeDescription
<!--<TextBlock Text="{Binding RelativeSource={RelativeSource FindAncestor, AncestorType=DataGrid, AncestorLevel=1}, Path=QuantityTypeDescription}" Margin="5,0,0,0"/>-->
<TextBlock Text="{Binding Amount}" Margin="5,0,0,0"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
Use ElementName Binding to refer to your main DataGrid's SelectedItem
<DataGrid Name="MainDataGrid" ItemsSource="{Binding Orders}" AutoGenerateColumns="False" IsReadOnly="True" HorizontalScrollBarVisibility="Auto">
<DataGrid.Columns>
<DataGridTextColumn Header="Trade" Binding="{Binding TransactionTypeDescription}" Width="*"/>
<DataGridTextColumn Header="Adjustment" Binding="{Binding QuantityTypeDescription}" Width="Auto"/>
</DataGrid.Columns>
<DataGrid.RowDetailsTemplate>
<DataTemplate>
<!--Order Summary-->
<StackPanel Orientation="Vertical">
<StackPanel Background="DarkSlateGray" Orientation="Vertical">
<StackPanel Orientation="Horizontal" HorizontalAlignment="Center">
<TextBlock Text="{Binding TransactionTypeDescription}" FontWeight="Bold" Margin="5,0,0,0" FontSize="14" Foreground="White"/>
</StackPanel>
<TextBlock Name="Name" Text="{Binding SecurityName}" HorizontalAlignment="Center" FontWeight="Bold" Foreground="White" Background="DarkSlateGray"/>
</StackPanel>
<StackPanel Orientation="Vertical">
<ItemsControl ItemsSource="{Binding Allocations}">
<ItemsControl.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding ElementName=MainDataGrid,Path=SelectedItem.QuantityTypeDescription}" Margin="5,0,0,0"/>
<TextBlock Text="{Binding Amount}" Margin="5,0,0,0"/>
</StackPanel>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</StackPanel>
</StackPanel>
</DataTemplate>
</DataGrid.RowDetailsTemplate>
</DataGrid>
I have listBox and i want to see the selected item ftom the listBox on some textBox.
(the Collection is a list of string)
I trying to write the code but this is not working.
<ListBox x:Name="Collection__" Grid.Row="0" ItemsSource="{Binding Collection}" />
<StackPanel Grid.Row="0" Grid.Column="1" Orientation="Vertical" Margin="5">
<DockPanel>
<TextBlock DockPanel.Dock="Left" Text="Collection name:"/>
<TextBox DockPanel.Dock="Left" Margin="5,0" Text="{Binding ElementName=Collection__, Path=SelectedItem}"/>
</DockPanel>
</StackPanel>
found it ...
<StackPanel>
<ListBox x:Name="ElementListBox" ItemsSource="{Binding Elements}"
IsSynchronizedWithCurrentItem="True">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Vertical">
<TextBlock Text="{Binding Name}"/>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<TextBox Text="{Binding Elements/Name}"/>
</StackPanel>
I have a listbox control in my app.
I want to change his style to being look like to Datagrid (borders, columns, row...).
I don't want to using stantard datagrid - because its control cannot binding itemtemplte.
I trying to do it:
<ListBox
ItemsSource="{Binding Items}"
HorizontalContentAlignment="Stretch"
VerticalContentAlignment="Stretch"
Name="listBox1"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" >
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Id}" Margin="5"/>
</Border>
<Border BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Name}" Margin="5"/>
</Border>
</StackPanel>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
But it not looking good - as following:
it what i want to achieve:
Using Grid.IsSharedSizeScope
result
i believe you want the columns to be re-sized based on your string length, so Grid.IsSharedSizeScope is your choice here
example xaml
<ListBox ItemsSource="{Binding Items}"
Grid.IsSharedSizeScope="True">
<ListBox.Resources>
<Style TargetType="ListBoxItem">
<Setter Property="Template">
<Setter.Value>
<ControlTemplate TargetType="ListBoxItem">
<ContentPresenter />
</ControlTemplate>
</Setter.Value>
</Setter>
</Style>
</ListBox.Resources>
<ListBox.ItemTemplate>
<DataTemplate>
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition SharedSizeGroup="name" />
<ColumnDefinition />
</Grid.ColumnDefinitions>
<Border BorderThickness="1"
BorderBrush="Black">
<TextBlock Text="{Binding Name}"
Margin="5" />
</Border>
<Border BorderThickness="1"
Grid.Column="1"
BorderBrush="Black">
<TextBlock Text="{Binding Id}"
Margin="5" />
</Border>
</Grid>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
if you move SharedSizeGroup to id like below
<Grid.ColumnDefinitions>
<ColumnDefinition />
<ColumnDefinition SharedSizeGroup="id" />
</Grid.ColumnDefinitions>
result
Using ListView with GridView
You have an option to use list view with grid view which will have same appearance as grid with flexibility of list
eg
<ListView ItemsSource="{Binding SourceItems}">
<ListView.View>
<GridView>
<GridViewColumn Header="Column1"
DisplayMemberBinding="{Binding Column1}" />
<GridViewColumn Header="Column2"
DisplayMemberBinding="{Binding Column2}" />
</GridView>
</ListView.View>
</ListView>
GridViewColumn offers you to modify CellTemplate, HeaderTemplate, HeaderContainerStyle, HeaderStringFormat etc.
I am sure you can achieve this using a grid control (It supports binding and everything else)
To fix your problem, you will have to give fixed widths to both your borders inside your stackpanel then your listbox items will look like a grid control.
<StackPanel Orientation="Horizontal" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<Border Width="150" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Id}" Margin="5"/>
</Border>
<Border Width="50" BorderThickness="1" BorderBrush="Black">
<TextBlock Text="{Binding Name}" Margin="5"/>
</Border>
</StackPanel>
Please let us know what problem you are having with GridControl and maybe we can fix that as well
Edit. If you were using a DataGrid your template would look like
<DataGrid ItemsSource="{Binding Items}" AutoGenerateColumns="False" HeadersVisibility="None">
<DataGrid.Columns>
<DataGridTemplateColumn Header="" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text={Binding Id}/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
<DataGridTemplateColumn Header="" Width="SizeToCells" IsReadOnly="True">
<DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<TextBlock Text={Binding Name}/>
</DataTemplate>
</DataGridTemplateColumn.CellTemplate>
</DataGridTemplateColumn>
</DataGrid.Columns>
</DataGrid>
Please note that I have set HeaderVisibility to false so that it doesnt look like a datagrid but instead looks like a list
I was wondering if I was missing something obvious.
I have a simple window with a ListView with 3 columns in it.
One displays text and the other two have combo boxes in them.
The ListView has approx. 500 records and the Comboboxes both pull from the same contact list which has approx. 8,000 records in it.
I am using MVVM.
This window takes for ever to open and once it does open it is practically frozen solid (it moves so slow)
the queries to the database take under ten seconds (I log when the VM is fully loaded) then it takes two or three minutes to open the window.
I made sure to store both lists in List<T> in my VM to make sure its not reprocessing the data or anything like that.
As you can see below. I've tried explicitly using Virtualizing Stack Panel but that did not help much.
Thank you for any help
<DataTemplate x:Key="ComboboxItemTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto" />
<ColumnDefinition Width="*" />
</Grid.ColumnDefinitions>
<Grid.RowDefinitions>
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
<RowDefinition Height="Auto" />
</Grid.RowDefinitions>
<Image Grid.RowSpan="3" Source="{Binding ImageURL, IsAsync=True}" Width="50" />
<TextBlock Grid.Column="1" Text="{Binding Name}" />
<TextBlock Grid.Column="1" Grid.Row="1" Text="{Binding Email}" />
<TextBlock Grid.Column="1" Grid.Row="2" Text="{Binding CampusName}" />
</Grid>
</DataTemplate>
<ListView ItemsSource="{Binding MainList}" IsSynchronizedWithCurrentItem="True" Grid.RowSpan="2">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
<ListView.View>
<GridView>
<GridViewColumn Width="200" Header="Internal">
<GridViewColumn.CellTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Name}" FontWeight="Bold" />
<TextBlock Text="{Binding MName}" />
<TextBlock Text="{Binding CampusName}" />
</StackPanel>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="200" Header="Contact1">
<GridViewColumn.CellTemplate>
<DataTemplate>
<ComboBox ItemsSource="{Binding Source={StaticResource VM}, Path=ContactList, IsAsync=True}" SelectedValue="{Binding HisContactID}" SelectedValuePath="id" ItemTemplate="{StaticResource ComboboxItemTemplate}" Background="{Binding HisColor}" Margin="0,82,0,115" Grid.Row="1" Grid.Column="1">
<ComboBox.ItemsPanel>
<ItemsPanelTemplate>
<VirtualizingStackPanel />
</ItemsPanelTemplate>
</ComboBox.ItemsPanel>
</ComboBox>
</DataTemplate>
</GridViewColumn.CellTemplate>
</GridViewColumn>
<GridViewColumn Width="200" Header="Contact2">
...
</GridViewColumn>
</GridView>
</ListView.View>
</ListView>
I had the same issue and finally figured it out...
It happens that the ListView was nested inside an Infragistic TabControl and each time something was bound inside the ListView (ie: ComboBoxes), the "SelectionChange" of the TabControl was firing, causing the delay...
I've also tested with a native Microsft TabControl and I got fairly the same behavior, but somewhat a bit more performant.
I solved the issue by validating the SelectionChangedEventArgs... making sure the e.AddedItems contains only "TabItem" (and not ComboBoxes) before processing.
Hope it helps,