Reputation: 1187
Is it possible to set the control template of my listview with xaml when I click a button?
Right now I know how to set my contenttemplate when I have my ListViewItem
selected, but not how to change my control template when something outside of the listview changes.
I'd like to change my ListItemTemplate
to use the RentTemplate
or the BuyTemplate
when clicking the corresponding button.
<Button x:Name="RentButton" />
<Button x:Name="BuyButton" />
<ListView Name="ItemsList">
<ListView.Resources>
<!-- unselected item template -->
<DataTemplate x:Key="DefaultItemTemplate">
</DataTemplate>
<!-- selected item template -->
<DataTemplate x:Key="SelectedItemTemplate">
</DataTemplate>
<DataTemplate x:Key="RentTemplate">
</DataTemplate>
<DataTemplate x:Key="BuyTemplate">
</DataTemplate>
</ListView.Resources>
<ListView.ItemContainerStyle>
<Style TargetType="ListBoxItem">
<!-- set properties for all items -->
<Setter Property="ContentTemplate" Value="{StaticResource DefaultItemTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<!-- change what the selected item looks like -->
<Setter Property="ContentTemplate" Value="{StaticResource SelectedItemTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
</ListView.ItemContainerStyle>
</ListView>
Edit
I'm trying to use DataTriggers to select what template to use when I change a property (which I'll change when I click my buttons). I don't think this situation is ideal, but I don't know any other way.
The problem now is that I can't seem to mix Property triggers and DataTriggers in the same MultiTrigger.
The scenario I'm trying to make is the following:
If I push the BuyButton
I want to see the BuyTemplate
.
Same for RentButton
with RentTemplate
.
BUT when I press a third button OverviewButton
I'd like to make a choice between two templates, depending on whether the current ListBoxItem
is selected or not.
Or am I misusing DataTemplates and DataTriggers and is there a better way to achieve this?
<Window.Resources>
<!-- unselected item template -->
<DataTemplate x:Key="DefaultItemTemplate">
</DataTemplate>
<!-- selected item template -->
<DataTemplate x:Key="SelectedItemTemplate">
</DataTemplate>
<DataTemplate x:Key="RentTemplate">
</DataTemplate>
<DataTemplate x:Key="BuyTemplate">
</DataTemplate>
<Style x:Key="ListViewItemStyle" TargetType="{x:Type ListBoxItem}">
<Style.Triggers>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Property="IsSelected" Value="false"/>
<Condition Binding="{Binding SelectedType}" Value="Overview" />
</MultiDataTrigger.Conditions>
<Setter Property="ContentTemplate" Value="{StaticResource DefaultItemTemplate}" />
</MultiDataTrigger>
<MultiDataTrigger>
<MultiDataTrigger.Conditions>
<Condition Property="IsSelected" Value="true"/>
<Condition Binding="{Binding SelectedType}" Value="Overview" />
</MultiDataTrigger.Conditions>
<Setter Property="ContentTemplate" Value="{StaticResource SelectedItemTemplate}" />
</MultiDataTrigger>
<DataTrigger Binding="{Binding SelectedType}" Value="Rent">
<Setter Property="ContentTemplate" Value="{StaticResource RentTemplate}" />
</DataTrigger>
<DataTrigger Binding="{Binding SelectedType}" Value="Buy">
<Setter Property="ContentTemplate" Value="{StaticResource BuyTemplate}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
Upvotes: 0
Views: 1564
Reputation: 1187
I've ultimately solved it like this:
<Style x:Key="OverviewListViewItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource DefaultItemTemplate}" />
<Style.Triggers>
<Trigger Property="IsSelected" Value="true">
<Setter Property="ContentTemplate" Value="{StaticResource SelectedItemTemplate}" />
</Trigger>
</Style.Triggers>
</Style>
<Style x:Key="BuyListViewItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource BuyTemplate}" />
</Style>
<Style x:Key="RentListViewItemStyle" TargetType="{x:Type ListBoxItem}">
<Setter Property="ContentTemplate" Value="{StaticResource RentTemplate}" />
</Style>
And just doing this in my view:
private void RentButton_Click(object sender, RoutedEventArgs e)
{
ItemsList.ItemContainerStyle = (System.Windows.Style)Resources["RentListViewItemStyle"];
_MainWindowViewModel.RentButton_Click();
}
private void BuyButton_Click(object sender, RoutedEventArgs e)
{
ItemsList.ItemContainerStyle = (System.Windows.Style)Resources["BuyListViewItemStyle"];
_MainWindowViewModel.BuyButton_Click();
}
private void PropertyButton_Click(object sender, RoutedEventArgs e)
{
ItemsList.ItemContainerStyle = (System.Windows.Style)Resources["OverviewListViewItemStyle"];
_MainWindowViewModel.PropertyButton_Click();
}
This was the easiest way to switch styles without losing too much time with figuring out the right combination of voodoo and Triggers.
Upvotes: 0
Reputation: 8111
You can use a DataTemplateSelector
.
A tutorial can be found here:
http://tech.pro/tutorial/807/wpf-tutorial-how-to-use-a-datatemplateselector
Some code from the tutorial:
public class ImgStringTemplateSelector : DataTemplateSelector
{
public DataTemplate ImageTemplate { get; set; }
public DataTemplate StringTemplate { get; set; }
public override DataTemplate SelectTemplate(object item,
DependencyObject container)
{
String path = (string)item;
String ext = System.IO.Path.GetExtension(path);
if (System.IO.File.Exists(path) && ext == ".jpg")
return ImageTemplate;
return StringTemplate;
}
}
XAML:
<Window.Resources>
<local:RelativeToAbsolutePathConverter x:Key="relToAbsPathConverter" />
<DataTemplate x:Key="stringTemplate">
<TextBlock Text="{Binding}"/>
</DataTemplate>
<DataTemplate x:Key="imageTemplate">
<Image Source="{Binding Converter={StaticResource relToAbsPathConverter}}"
Stretch="UniformToFill" Width="200"/>
</DataTemplate>
<local:ImgStringTemplateSelector
ImageTemplate="{StaticResource imageTemplate}"
StringTemplate="{StaticResource stringTemplate}"
x:Key="imgStringTemplateSelector" />
</Window.Resources>
<ListView ScrollViewer.CanContentScroll="False"
ItemsSource="{Binding ElementName=This, Path=PathCollection}"
ItemTemplateSelector="{StaticResource imgStringTemplateSelector}">
</ListView>
The templates and the selector can be specidifed in the resources, the control must then reference the DataTemplateSelector.
Upvotes: 2