I have a list view and 2 resources for display the list's view: BooksGridView & ImageDetailView.
The ViewModel has a string property named ViewMode, which contains the name of the view i currently want to display. (It is changed from another control, using toolbars)
I am trying to change the selected view by using DataTrigger
, but I cant seem to get the View property to change.
When i set the View resource directly, the correct view is displayed. I also added background changes to make sure the data trigger is activated, and the background did change.
So I'm obviously missing something here...
<UserControl x:Class="eLibrary.View.FilteredBooksView"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:Converters="clr-namespace:eLibrary.Converters"
xmlns:Controls="clr-namespace:eLibrary.Controls"
xmlns:scm="clr-namespace:System.ComponentModel;assembly=WindowsBase"
xmlns:local="clr-namespace:eLibrary"
mc:Ignorable="d"
d:DesignHeight="300" d:DesignWidth="300">
<UserControl.Resources>
<Converters:CoverImageConverter x:Key="CoverImageConverter"/>
<BooleanToVisibilityConverter x:Key="BoolToVisConverter" />
<GridView x:Key="BooksGridView">
...
</GridView>
<Controls:TileView x:Key="ImageDetailView">
...
</Controls:TileView>
<CollectionViewSource x:Key="sortedBooks" Source="{Binding Books}">
<CollectionViewSource.SortDescriptions>
<scm:SortDescription PropertyName="Title" Direction="Ascending"/>
</CollectionViewSource.SortDescriptions>
</CollectionViewSource>
<Style TargetType="{x:Type ListView}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ViewMode}" Value="BooksGridView">
<Setter Property="View" Value="{StaticResource BooksGridView}"/>
<Setter Property="Background" Value="Red"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=ViewMode}" Value="ImageDetailView">
<Setter Property="View" Value="{StaticResource ImageDetailView}" />
<Setter Property="Background" Value="Blue"/>
</DataTrigger>
</Style.Triggers>
</Style>
</UserControl.Resources>
<ListView
VerticalAlignment="Stretch"
Name="BooksListView"
View="{StaticResource BooksGridView}"
SelectionMode="Extended"
ItemsSource="{Binding Source={StaticResource sortedBooks}}">
<ListView.Resources>
<Style TargetType="{x:Type ListViewItem}">
<Setter Property="IsSelected" Value="{Binding Path=IsSelected, Mode=TwoWay}" />
<Setter Property="Visibility" Value="{Binding Path=ShouldDisplay, Converter={StaticResource BoolToVisConverter} }" />
</Style>
</ListView.Resources>
</ListView>
</UserControl>
Thanks
Based off the sample on MSDN, the following works at changing the view based on a change in the ViewModel. The only difference I can see with your code is the use of DynamicResource
:
<Window x:Class="SDKSample.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="Custom View"
xmlns:l="clr-namespace:SDKSample"
Width="400" Height="500"
SourceInitialized="Window_SourceInitialized">
<Window.Resources>
<DataTemplate x:Key="centralTile">
<StackPanel Height="100" Width="90">
<Grid Width="70" Height="70" HorizontalAlignment="Center">
<Image Source="{Binding XPath=@Image}" Margin="6,6,6,9"/>
</Grid>
<TextBlock Text="{Binding XPath=@Name}" FontSize="13"
HorizontalAlignment="Center" Margin="0,0,0,1" />
<TextBlock Text="{Binding XPath=@Type}" FontSize="9"
HorizontalAlignment="Center" Margin="0,0,0,1" />
</StackPanel>
</DataTemplate>
<DataTemplate x:Key="iconTemplate">
<DockPanel Height="33" Width="150">
<Image Source="{Binding XPath=@Image}" Margin="2"/>
<TextBlock DockPanel.Dock="Top" Text="{Binding XPath=@Name}"
FontSize="13" HorizontalAlignment="Left"
Margin="0,0,0,1" />
<TextBlock Text="{Binding XPath=@Type}" FontSize="9"
HorizontalAlignment="Left" Margin="0,0,0,1" />
</DockPanel>
</DataTemplate>
<DataTemplate x:Key="checkbox">
<CheckBox IsChecked="{Binding IsSelected, RelativeSource= {RelativeSource AncestorType=ListViewItem}}"
Margin="0,1,1,1" >
</CheckBox>
</DataTemplate>
<XmlDataProvider x:Key="myXmlDataBase" XPath="/myXmlData">
<x:XData>
<myXmlData xmlns="">
<Item Name = "Fish" Type="fish" Image="images\fish.png"/>
<Item Name = "Dog" Type="animal" Image="images\dog.png"/>
<Item Name = "Flower" Type="plant" Image="images\flower.jpg"/>
<Item Name = "Cat" Type="animal" Image="images\cat.png"/>
</myXmlData>
</x:XData>
</XmlDataProvider>
<DataTemplate x:Key="DisplayImage">
<StackPanel Width="50">
<Image Source="{Binding XPath=@Image}"/>
</StackPanel>
</DataTemplate>
<GridView x:Key="gridView">
<GridViewColumn CellTemplate="{StaticResource checkbox}"/>
<GridViewColumn Header="Name" DisplayMemberBinding="{Binding XPath=@Name}"/>
<GridViewColumn Header="Type" DisplayMemberBinding="{Binding XPath=@Type}"/>
<GridViewColumn Header="Image" CellTemplate="{StaticResource DisplayImage}"/>
</GridView>
<l:PlainView x:Key="tileView" ItemTemplate="{StaticResource centralTile}" ItemWidth="100"/>
<l:PlainView x:Key="iconView" ItemTemplate="{StaticResource iconTemplate}" ItemWidth="150"/>
<Style TargetType="{x:Type ListView}">
<Style.Triggers>
<DataTrigger Binding="{Binding Path=ViewName}" Value="iconView">
<Setter Property="View" Value="{DynamicResource iconView}"/>
</DataTrigger>
<DataTrigger Binding="{Binding Path=ViewName}" Value="tileView">
<Setter Property="View" Value="{DynamicResource tileView}" />
</DataTrigger>
<DataTrigger Binding="{Binding Path=ViewName}" Value="gridView">
<Setter Property="View" Value="{DynamicResource gridView}" />
</DataTrigger>
</Style.Triggers>
</Style>
</Window.Resources>
<StackPanel>
<ListView Name="lv"
ItemsSource="{Binding Source={StaticResource myXmlDataBase}, XPath=Item}"
FontSize="12"
Background="LightBlue" >
<ListView.ContextMenu>
<ContextMenu>
<MenuItem Header="gridView" Click="SwitchViewMenu"/>
<MenuItem Header="iconView" Click="SwitchViewMenu"/>
<MenuItem Header="tileView" Click="SwitchViewMenu"/>
</ContextMenu>
</ListView.ContextMenu>
</ListView>
<TextBlock FontSize="16" Foreground="Blue">
CurrentView: <TextBlock Name="currentView" Text="{Binding Path=ViewName}"/>
</TextBlock>
<TextBlock>
Right-click in the content window to change the view.
</TextBlock>
</StackPanel>
</Window>
Code behind file:
using System;
using System.Windows;
using System.Windows.Controls;
namespace SDKSample
{
/// <summary>
/// Interaction logic for Window1.xaml
/// </summary>
public partial class Window1 : Window
{
public Window1()
{
InitializeComponent();
}
public MainViewModel ViewModel
{
get { return this.DataContext as MainViewModel; }
}
void SwitchViewMenu(object sender, RoutedEventArgs args)
{
MenuItem mi = (MenuItem)sender;
ViewModel.ViewName = mi.Header.ToString();
}
private void Window_SourceInitialized(object sender, EventArgs e)
{
ViewModel.ViewName = "gridView";
}
}
}
And finally the ViewModel class:
using System;
using System.Collections.Generic;
using System.Text;
using System.ComponentModel;
namespace SDKSample
{
public class MainViewModel : INotifyPropertyChanged
{
public string ViewName
{
get { return viewName; }
set
{
if (viewName == value)
return;
viewName = value;
NotifyPropertyChanged("ViewName");
}
}
private string viewName;
public event PropertyChangedEventHandler PropertyChanged;
void NotifyPropertyChanged(string name)
{
if (this.PropertyChanged != null)
this.PropertyChanged(this, new PropertyChangedEventArgs(name));
}
}
}
I cannot see any obvious issue with your code you provided. I would usually suggest checking that the DataTrigger
is being trigger, however you have already tested that with the Background
property.
Looking at sample on MSDN ( link ) the only difference in implementation is that, in the sample, switch the ListView.View
is changed in code.
BookListView.View = this.FindResource("BooksGridView") as ViewBase;
...
Hmm, perhaps the view resource may not be able to found and it is failing.
...
All I can suggest is look at the sample. Sorry couldn't be much more help.
The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.