I have 3 List views. They are very similar. The only difference is that their ItemsSource binds to different variables. Is there a way to create a template list view with unknown ItemsSource, and I can pass a parameter to fill that ItemsSource?
My code is something like this:
<ListView Name="View1" ItemsSource={"Binding Student1"}>
<TextBlock Text={"Binding Name"}/>
</ListView>
<ListView Name="View2" ItemsSource={"Binding Student2"}>
<TextBlock Text={"Binding Name"}/>
</ListView>
<ListView Name="View3" ItemsSource={"Binding Student3"}>
<TextBlock Text={"Binding Name"}/>
</ListView>
Edit:
I might have expressed my question in a wrong way. I would like to have a separate user control view called "StudentView":
<ListView ItemsSource=Parameter1>
<TextBlock Text={"Binding Name"}/>
</ListView>
So that in my main window, I can do something like this:
<local:StudentView Parameter1={"Binding Student1"}/>
You are on the right track with thinking about templating
What you are looking for is something called a ControlTemplate.
Your ControlTemplate would then target the ListView control and use the key word TemplateBinding to pass through the ItemsSource binding from your ListView
You would look to add this as a window resource as shown below.
<Window.Resources>
<ControlTemplate x:Key="ListViewTemplate" TargetType="ListView">
<ListView ItemsSource="{TemplateBinding ItemsSource}">
<ListView.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Name}"/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ControlTemplate>
</Window.Resources>
This would enable you to use this template on your ListView controls as shown below
<ListView Template="{StaticResource ListViewTemplate}" ItemsSource="{Binding PersonList}"/>
<ListView Template="{StaticResource ListViewTemplate}" ItemsSource="{Binding PersonList1}"/>
<ListView Template="{StaticResource ListViewTemplate}" ItemsSource="{Binding PersonList2}"/>
Hope this gives you what you were looking for
Related
I have a ListBox in my WPF MVVM app using the following code:
<GroupBox Grid.Column="0" Margin="0,0,0,-58">
<DockPanel>
<TextBlock DockPanel.Dock="Top"
HorizontalAlignment="Center"
Margin="0,0,0,8"
FontWeight="Bold"
Text="{x:Static p:Resources.AvaliableLEDsLabel}" />
<ListBox Name="AvailableLEDsListbox" SelectionMode="Extended"
dd:DragDrop.IsDragSource="True"
dd:DragDrop.IsDropTarget="True"
dd:DragDrop.DropHandler="{Binding}"
ItemTemplate="{StaticResource DataTemplateListBoxItem}"
ItemsSource="{Binding AvailableLeds}"
ScrollViewer.VerticalScrollBarVisibility="Hidden"
>
<ListBox.GroupStyle>
<StaticResource ResourceKey="StyleListBoxGroup" />
</ListBox.GroupStyle>
</ListBox>
</DockPanel>
</GroupBox>
This displays grouped lists of devices, with LEDs under them. The DataTemplate is the following:
<GroupStyle x:Key="StyleListBoxGroup">
<GroupStyle.HeaderTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<Button Command="{Binding HideGroupCommand}">X</Button>
<TextBlock VerticalAlignment="Center"
HorizontalAlignment="Left"
FontWeight="Bold"
Text="{Binding Name}" />
</StackPanel>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
<DataTemplate x:Key="DataTemplateListBoxItem">
<TextBlock x:Name="LedId" Text="{Binding LedId}"/>
</DataTemplate>
I would like to make the X button in the header hooked up to the HideGroupCommand toggle the hiding of all the items under that particular header. How would I go about doing this? Thanks in advance.
You have few options.
First one :
You would need to have a property in your view model something like 'ListBoxVisibility' then u would bind that property to your UI. In command text u just changed visibility property of that property in view model- so u have it reflected on UI. This visibility property can be of type 'bool' , or 'Visibility' or whatever. Only if it's type of Visibility u don't need converter when binding.
NOTE : Some people use it - even though it kinda goes out of general principel of MVVM patter. But sometimes u have to do it.
Second
If wanna stick to MVVM , then u need to fully separate your UI from your viewmodel. Create click event and change visibility.
I have to do a Master/Detail in UWP
1- If you're in Laptop:
The responsible GridView of show the data of this person appear.
So when you select a item is binded to ViewModel.
<ScrollViewer x:Name="ScrollLista" Grid.Column="0" Grid.Row="1">
<ListView x:Name="Lista" ItemsSource="{Binding Lista}" ItemClick="Lista_ItemClick" SelectedItem="{Binding PersonaSeleccionada, Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}">
<ListView.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding nombre}" />
<TextBlock Text="{Binding apellido}" />
</StackPanel>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</ScrollViewer>
<Grid x:Name="CRUD" Grid.Column="1" Grid.Row="1" DataContext="{Binding PersonaSeleccionada}" Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
...
</Grid>
2- When is a mobile:
Only will appear the list and when I select a item this should be two things.
Call to ViewModel by binding using SelectedItem.
Call to code behind using ItemClick, this will be in charge of calling another page.
The problem: ItemClick not working, not call to Lista_ItemClick... How can I call a method and send the item selected to code behind?
For click event to work, IsItemClickEnabled="True" should be added to the ListView.
I'm trying to organize the items in a combobox into groups. To do this I've created an object that has project and group name strings. I then set the GroupStyle and ItemTemplate to display these values. However, Currently, only the project string is displayed in the combobox (and the box has a red border, indicating some kind of error).
Here's the xaml for my combobox:
<ComboBox x:Name="comboBoxProjects" Margin="165,90,28,0" Grid.Column="0" VerticalAlignment="Top" Height="25"
IsSynchronizedWithCurrentItem="True" SelectedIndex="0" Style="{StaticResource ComboBoxDefault}"
ItemsSource="{Binding Path=ProjectClientSelections.ProjectGroupItems,Mode=TwoWay, UpdateSourceTrigger=PropertyChanged}"
SelectedItem="{Binding Path=ProjectClientSelections.SelectedProject, UpdateSourceTrigger=PropertyChanged}">
<ComboBox.GroupStyle>
<GroupStyle>
<GroupStyle.HeaderTemplate>
<DataTemplate>
<TextBlock Text="{Binding GroupName}"/>
</DataTemplate>
</GroupStyle.HeaderTemplate>
</GroupStyle>
</ComboBox.GroupStyle>
<ComboBox.ItemTemplate>
<DataTemplate>
<TextBlock Text="{Binding Project}"/>
</DataTemplate>
</ComboBox.ItemTemplate>
</ComboBox>
Does anyone see where I'm going wrong?
In GroupStyle, the DataContext is not your item (the type contained in your ItemsSource), but a CollectionViewGroup object, which is formed based on the collection of items that you have grouped. Because of this you have to declare a binding path to one of the properties in CollectionViewGroup, for example, based on your code you probably want to use Name property. See MSDN CollectionViewGroup Class
Change your GroupStyle.HeaderTemplate to this:
<DataTemplate>
<TextBlock Text="{Binding Name}" />
</DataTemplate>
You don't show how you have formed your GroupDescriptions. If you have not grouped the items already, you can do it in following way (assuming the XAML you have provided is contained inside Window and Window's and GroupBox's DataContext is the same):
<Window.Resources>
<CollectionViewSource
Source="{Binding ProjectClientSelections.ProjectGroupItems}"
x:Key="GroupedProjectItems">
<CollectionViewSource.GroupDescriptions>
<PropertyGroupDescription
PropertyName="GroupName" />
</CollectionViewSource.GroupDescriptions>
</CollectionViewSource>
</Window.Resources>
After this change GroupBox ItemSource binding to the following (directly to CollectionViewSource resource):
ItemsSource="{Binding Source={StaticResource GroupedProjectItems}}"
I'm totaly new to wpf. I try to create a nested datatemplate like this layout (datatemplate inside another datatemplate). I managed to create a datatemplate and to connect to "Object A" in an ObservableCollection, which worked really well. Now I need to have a nested ObservableCollection in each Object A to display Object B and Object C in columns. But I don't really know how to do that and can't find examples.
Maybe anyone could give me a hint?
Thanks and regards,
Marlene
Assuming you're using a ListView or ListBox to display a collection of Object A (lets call it ObjectACollection), and that Object A has properties named (in this example) ObjectBCollection and ObjectCCollection you could do something like this:
<UserControl xmlns:namespaceA="clr-namespace:MyProj.Models.ObjectANamespace"
xmlns:namespaceB="clr-namespace:MyProj.Models.ObjectBNamespace"
xmlns:namespaceC="clr-namespace:MyProj.Models.ObjectCNamespace" >
<ListBox ItemsSource="{Binding ObjectACollection}">
<ListBox.ItemTemplate>
<DataTemplate DataType="namespaceA:ObjectA">
<StackPanel Orientation="Horizontal">
<ListBox ItemsSource="{Binding ObjectBCollection}">
<ListBox.ItemTemplate>
<DataTemplate DataType="namespaceB:ObjectB">
<TextBlock Text="{Binding ObjectBProperty}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
<ListBox ItemsSource="{Binding ObjectCCollection}">
<ListBox.ItemTemplate>
<DataTemplate DataType="namespaceC:ObjectC">
<TextBlock Text="{Binding ObjectCProperty}"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
</UserControl>
i'm trying to make my App Design responsive.
i have ListView that have a dataTemplate with defined property:
<ListView x:Name="listView" ItemsSource="{x:Bind manager.recentVideos}"
IsItemClickEnabled="True"
ItemClick="ListView_ItemClick">
<ListView.ItemTemplate>
<DataTemplate x:DataType="data:VideoItem" >
<Image Width="200"
Source="{x:Bind TileImage}" Margin="-10,0,-10,5"
></Image>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
I'm trying to change Image Width with VisualStateTrigers...
so i need to Target Setter to this property somehow....
Someone please help! :)
VisualStateTriggers are not supported inside DataTemplates. Just use a UserControl as your DataTemplate as is suggested in this:
AdaptiveTrigger and DataTemplate