【问题标题】:Switching Listviews with templates in app.xaml?在 app.xaml 中使用模板切换列表视图?
【发布时间】:2012-02-29 19:44:10
【问题描述】:

我制作了 2 个列表视图,其中 1 个带有图像 + 姓名和姓氏,1 个仅显示图像(在列表视图的 Wrap 面板中)。第一个:

  <ListView x:Name="lsvsomething" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" GotFocus="lsv_GotFocus" SelectionChanged="lsv_selectionchanged" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
            <ListView.View>
                <GridView>
                    <GridViewColumn Width="auto">
                        <GridViewColumn.CellTemplate>
                            <DataTemplate>
                                <Image HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="50" Source="{Binding image}" Stretch="Fill"/>
                            </DataTemplate>
                        </GridViewColumn.CellTemplate>
                    </GridViewColumn>
                    <GridViewColumn Width="auto" DisplayMemberBinding="{Binding name}">
                        <GridViewColumnHeader Content="name" Tag="name" Click="SortClick"/>
                    </GridViewColumn>
                    <GridViewColumn Width="auto" DisplayMemberBinding="{Binding lastname}">
                        <GridViewColumnHeader Content="lastname" Tag="lastname" Click="SortClick" />
                    </GridViewColumn>
                </GridView>
            </ListView.View>
    </ListView>

第二个(只有图片):

 <ListView x:Name="lsvsomething" Grid.Column="1" Grid.Row="1" Grid.RowSpan="2" GotFocus="lsv_GotFocus" SelectionChanged="lsv_selectionchanged" ScrollViewer.HorizontalScrollBarVisibility="Disabled">
    <ListView.ItemsPanel>
                        <ItemsPanelTemplate>
                            <WrapPanel Orientation="Horizontal" />
                        </ItemsPanelTemplate>
                    </ListView.ItemsPanel>
                    <ListView.View>
                        <GridView>
                            <GridViewColumn Width="60">
                                <GridViewColumn.CellTemplate>
                                    <DataTemplate>
                                        <Image HorizontalAlignment="Center" VerticalAlignment="Center" Width="50" Height="50" Source="{Binding image}" Stretch="Fill"/>
                                    </DataTemplate>
                                </GridViewColumn.CellTemplate>
                            </GridViewColumn>
                        </GridView>
                    </ListView.View>
  </ListView>

现在它们都有 ListView.View,我想把它们放在“模板”中吗?在 app.xaml 中,但我不知道该怎么做。第二个 Listview 也使用 ItemsPanelTemplate 使其成为一个环绕面板。我找到了如何在 app.xaml (ItemsPanel="{DynamicResource somename}") 中保存那个但是我在多个窗口上使用这个列表视图,所以我想在应用程序中同时保存它们(制作它们的模板?)。 xml 文件。然后我也应该能够在运行时切换它们。 (itemsource在“codebehind”中设置)

【问题讨论】:

  • 我在用谷歌搜索 atm 并认为我必须使用 setter 为 controltemplate 制作一个样式 ^^。但随后绑定不再起作用

标签: c# wpf templates xaml listview


【解决方案1】:

“模板”确实不是确切的定义。我假设您真的想要列表视图的某种可重用性。选项很少

选项 1(首选)将每个 ListView 放在 UserControl 中。这将是一个独立的 XAML 文件, 元素位于根目录, 元素是其唯一的子元素(不需要面板,因为您只有一个元素。XAML 看起来像:

<UserControl x:Class="SO.NameAndImageList"
    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"
    mc:Ignorable="d"
    d:DesignHeight="300" d:DesignWidth="300"
    >
    <ListView ...>
        ...
    </ListView>
</UserControl>

要使用此用户控件,请定义“本地”命名空间以指向您的代码:

<Window ...
    xmlns:local"clr-namespace:SO">

    ...
    <local:NameAndImageList />
    ...
</Window>

选项 2 创建一个 DataTemplate,它提供一个代表您的列表的自定义类型。

在代码中(通常称为 ViewModel,在 MVVM 模型中),定义以下类型:

public class PersonCollection : ObservableCollection<Person> { }

您的类型派生自 ObservableCollection 的 Person(包含该项目的类),没有添加。这只是 XAML 可以理解的别名。然后,在 app.xaml 文件的 部分中,定义以下模板:

<DataTemplate TargetType="{x:Type local:PersonCollection}" x:Key="ImageAndNameTemplate">
    <ListBox ...>
        ...
    </ListBox>
</DataTemplate>

为了重用,只需将 PersonCollection 数据(通常来自 DataContext)放在任何面板中,或使用 ContentControl 中的绑定:

<Window ... >
    <Window.DataContext>
        <!-- Instantiate the data. There are many other ways to do that -->
        <local:PersonCollection>
            <local:Person Name="..." Image="..." />
            <local:Person Name="..." Image="..." />
            <local:Person Name="..." Image="..." />
            ...
        </local:PersonCollection>
    </Window.DataContext>

    ...
    <ContentControl Content="{Binding}" ContentTemplate="{StaticResource ImageAndNameTemplate}" />

</Window>

【讨论】:

  • 对于您的回答,我正在尝试您的第一个解决方案(因为您说这是首选方法)。但是我不能再设置 Itemsource 了?我给它一个 x:Name="theusercontroltest" 然后我想在代码隐藏中执行此操作:theusercontroltest.ItemsSource = mystaticobservablecollectionofpersons;
  • 好吧,我知道了如何修复项目源,我将不得不使用 usercontroltest.DataContext = mystaticobservablecollectionofpersons;然后在用户控件中我将设置 ItemsSource={Binding} 但是我现在如何能够在运行时切换 2 个用户控件?
  • @Maximc - 你给谁 x:Name="theusercontroltest" 属性?如果你这样做,它应该是 元素(在用户控件内)。然后,您应该能够从用户控件背后的代码访问它。或者,当您在主窗口中使用 时,您可以设置 UserControl.DataContext 属性。然后,在用户控件上,使用 Binding:
  • @Maximc - 要在两个用户控件之间切换,您有两个选择: (1) 将 UserControl 放在 ContentControl 中,然后在代码中替换 Content 属性。 (2) 从上面切换到选项 2,并替换 ContentTemplate。对不起,我不知道这是你的意图。当您想用不同的视图(模板)呈现相同的数据时 - 这种方法被认为更“正确”。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2013-06-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多