WinUI3 - bind ContentControl to CollectionViewSource CurrentItem instead of collection? - xaml

When an item is selected in my ListView, I want to display a specific user control in the my ContentControl.
Using the following code, my content control merely displays "Microsoft.UI.Xaml.Data.CollectionView". I understand the ContentControl is trying to bind to the entire list, but how do I tell it to bind to the CollectionViewSource's CurrentItem?
<Page.Resources>
<CollectionViewSource x:Name="PChoicesCollectionView" Source="{x:Bind ViewModel.PChoices}"/>
</Page.Resources>
<ListView ItemsSource="{Binding Source={StaticResource PChoicesCollectionView}}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="p:PBase">
<Grid>
<TextBlock Text="{x:Bind Name.Name}" FontSize="18" FontWeight="SemiBold"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ContentControl ContentTemplateSelector="{StaticResource pDataTemplateSelector}" Content="{Binding Source={StaticResource PChoicesCollectionView}}"/>

You could bind to the SelectedItem property of the ListView:
<ListView Name="lv"
ItemsSource="{Binding Source={StaticResource PChoicesCollectionView}}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="p:PBase">
<Grid>
<TextBlock Text="{Binding}" FontSize="18" FontWeight="SemiBold"/>
</Grid>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
<ContentControl ContentTemplateSelector="{StaticResource pDataTemplateSelector}"
Content="{Binding SelectedItem, ElementName=lv}"/>

Related

Access property in ListView that is not coming from ItemsSource

My ListView is bound to MyTexts list. Nevertheless i need to bind TextCell's Text to property that is not comming from Texts (StandAloneProperty). How can i do that?
<ListView
SelectedItem="{Binding SelectedText, Mode=TwoWay}"
ItemsSource="{Binding MyTexts}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding StandAloneProperty, StringFormat='Value: {0}'}"
TextColor="{Binding Color}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Set your binding Source to the current page, and access to StandAloneProperty, from BindingContext which is your ViewModel.
<ContentPage x:Name="pageRef"
...
<ListView
SelectedItem="{Binding SelectedText, Mode=TwoWay}"
ItemsSource="{Binding MyTexts}">
<ListView.ItemTemplate>
<DataTemplate>
<TextCell
Text="{Binding Source={x:Reference pageRef} Path=BindingContext.StandAloneProperty, StringFormat='Value: {0}'}"
TextColor="{Binding Color}"
/>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>

Sending SelectedIndex of ListView to ViewModel through CommandParameter

after a quite bit of googling I haven't found answer on this problem.
I have this ListView
<ListView x:Name="itemListView" ItemsSource="{Binding History}" HorizontalAlignment="Stretch">
<ListView.ItemContainerStyle>
<Style TargetType="ListViewItem">
<Setter Property="HorizontalContentAlignment" Value="Stretch"></Setter>
</Style>
</ListView.ItemContainerStyle>
<ListView.ItemTemplate>
<DataTemplate>
<Border Style="{StaticResource Border}" Background="{ThemeResource GradientLinear}" HorizontalAlignment="Stretch">
<Grid>
<StackPanel Orientation="Vertical" Margin="10,10,10,10" HorizontalAlignment="Left" Grid.Row="0" Grid.Column="0">
<TextBlock Text="{Binding name}" />
<TextBlock Text="{Binding question}" TextWrapping="Wrap"/>
<TextBlock Text="{Binding vrijeme}"/>
</StackPanel>
<Button Width="50" Height="50" Opacity="0.6" Grid.Row="0" Grid.Column="1" Tag="{Binding name}"
Command="{Binding ElementName=itemListView, Path=DataContext.Delete}" CommandParameter="{Binding ElementName=itemListView, Path=SelectedIndex}"
HorizontalAlignment="Right">
<SymbolIcon
HorizontalAlignment="Center"
Width="48"
Height="48"
Symbol="Delete" />
</Button>
</Grid>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
Problem is probably in this part of the code
<Button Width="50" Height="50" Opacity="0.6" Grid.Row="0" Grid.Column="1" Tag="{Binding name}"
Command="{Binding ElementName=itemListView, Path=DataContext.Delete}" CommandParameter="{Binding ElementName=itemListView, Path=SelectedIndex}"
HorizontalAlignment="Right">
When I click Button, ListViewItem that contains that Button is not selected so I get -1 for SelectedIndex or just null if I target SelectedItem. It seems that clicking that button leaves containing ListViewItem unaffected. If I first click ListViewItem and than click button it works, SelectedItem is set in ListView of course, but I can't count user will understand that. My question is - is there any way to "force" Button to send me in CommandArgument SelectedItem or SelectedIndex. I know how to do that through code-behind but I am interested in solving this problem through MVVM.
Thanx in advance.

ListViewItem access property on viewmodel

I have a list of users on my viewmodel that I pass to the following listView:
<ListView
Background="Azure"
x:Name="ContactList"
ItemsSource="{Binding Path=User}"
SelectedItem="{Binding SelectedUser, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate>
<Border Width="300" Height="Auto" BorderThickness="1">
<StackPanel>
<TextBlock>
<Run Text="{Binding Name}" />
<Run Text="{Binding Age}" />
</TextBlock>
<CheckBox Visibility="{???}">
<TextBlock FlowDirection="LeftToRight"></TextBlock>
</CheckBox>
</StackPanel>
</Border>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
As you can see my DataTemplate contains a checkbox. I would like its Visibility to depend on a bool-property I have on my ViewModel. How can I access this property from within the listView?
From looking around here it seems like there are ways to access the ListView-items parent. I think that would do it for me. Can someone point me in the right direction . Thanks
The best way to do this is to include the visibility setting along with your user data. Assuming your view model visibility property is named CheckBoxVisibility, you would have something like this:
<ListView ItemsSource="{Binding}" ...>
<ListView.ItemTemplate>
<DataTemplate>
...
<Run Text="{Binding Path=User.Name}" />
<Run Text="{Binding Path=User.Age}" />
...
<CheckBox Visibility="{Binding Path=CheckBoxVisibility}">
...
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
In WPF, you can use a RelativeSource=RelativeAncestor binding; however, this is not available in Window Store/Windows Phone 8+ apps.

How to find LongListMuliselector inside another ListBox

I need to find the LongListMultiSelector inside ListBox .
<ListBox x:Name="ListBoxName" Width="400">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<Bewise:ExpanderControl x:Name="bewiseControl" HeaderText="{Binding Title, Mode=OneWay}" Width="400" >
<Bewise:ExpanderControl.ContentArea>
<toolkit:LongListMultiSelector ItemsSource="{Binding LstProdcuts}" x:Name="LongList">
<toolkit:LongListMultiSelector.ItemTemplate >
<DataTemplate>
<StackPanel >
<TextBlock Text="{Binding Title}" />
</StackPanel>
</DataTemplate>
</toolkit:LongListMultiSelector.ItemTemplate>
</toolkit:LongListMultiSelector>
</Bewise:ExpanderControl.ContentArea>
</Bewise:ExpanderControl>
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
i need to access LongList inside ListBoxName.I needed this LongList to get the selected item and itemSource or to add item to the selecteditem of the list
You could use the VisualTreeHelper class in order to access elements within.
Example!

Access property of DataContext in ItemTemplate

My datacontext has two properties: Items which is a collection and DetailsVisiblity which is enum of type Visiblity.
On the page I have a Listbox with ItemsSource="{Binding Entries}". Inside the DataTemplate, I can bind stuff to properties of Items, but how do I get access to DetailsVisiblity which is a property of DataContext?
DataContext has two properties: ObservableCollection<Item> Entries, and Visibility DetailsVisiblity. Item class has two properties: Title and Details.
Here is the view. How do I bind Visiblity of the second TextBlock to DetailsVisiblity property?
<ListBox ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel>
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Details}" Visibility="{Binding ???}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
You could name the ListBox and in the Binding you reference it with ElementName, and in Path you use DataContext.DetailsVisibility
<ListBox x:Name="listBox" ItemsSource="{Binding Items}">
<ListBox.ItemTemplate>
<DataTemplate>
<StackPanel Orientation="Horizontal">
<TextBlock Text="{Binding Title}" />
<TextBlock Text="{Binding Details}"
Visibility="{Binding ElementName=listBox,
Path=DataContext.DetailsVisibilty}" />
</StackPanel>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>