簡體   English   中英

WPF:通過DataTrigger設置ListView視圖

[英]WPF: Setting ListView View via DataTrigger

我有一個列表視圖和2個資源,用於顯示列表的視圖:BooksGridView和ImageDetailView。

ViewModel有一個名為ViewMode的字符串屬性,它包含我當前想要顯示的視圖的名稱。 (它使用工具欄從另一個控件更改)

我試圖通過使用DataTrigger更改所選視圖,但我似乎無法更改View屬性。

當我直接設置View資源時,會顯示正確的視圖。 我還添加了背景更改以確保數據觸發器已激活,並且后台確實發生了變化。

所以我顯然在這里遺漏了一些東西......

<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>

謝謝

基於MSDN上的示例,以下內容適用於根據ViewModel中的更改更改視圖。 我能用你的代碼看到的唯一區別是使用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>

代碼隱藏文件:

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";
        }
    }
}

最后是ViewModel類:

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));
        }
    }
}

我看不到您提供的代碼存在任何明顯問題。 我通常會建議檢查DataTrigger是否正在觸發,但是您已經使用Background屬性對其進行了測試。

在MSDN( 鏈接 )上查看示例,實現的唯一區別是,在示例中,切換ListView.View在代碼中更改。

BookListView.View = this.FindResource("BooksGridView") as ViewBase;

...

嗯,也許視圖資源可能無法找到並且它失敗了。

...

我所能建議的只是查看樣本。 抱歉,沒有更多的幫助。

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM