【问题标题】:WPF - adding item of different template in listviewWPF - 在列表视图中添加不同模板的项目
【发布时间】:2014-06-26 16:28:19
【问题描述】:

当单击 ListView 上的项目时,我想制作另一个不同的模板以显示在其下方。我在 Window.Resources 中定义了模板,我考虑在单击项目时更改 ItemTemplate,添加新项目并将其更改为默认模板,但我使用 ListView 作为 ItemsSource 的列表它只显示一个模板,只是因为(现在) 它们在绑定中是相同的。我该怎么办?

代码:

public partial class MainWindow : Window
{
    public MainWindow()
    {
        InitializeComponent();
        List<TransactionItem> item = new List<TransactionItem>();
        item.Add(new TransactionItem() { category="Deska", index="2", name="Topielec"});
        List<object> transactions = new List<object>();
        transactions.Add(new Transaction() { name = "Maciek", surname = "Chludzinski", begin = "Dzisiaj 20:14", end = "Dzisiaj 21:14", price = "240 zł", remain = "42 minuty", items = item });
        obMainListBinding.ItemTemplate = (DataTemplate)this.FindResource("LessClientTemplate");
        MessageBox.Show(obMainListBinding.ItemTemplate.DataTemplateKey.ToString());
        transactions.Insert(1, new Transaction() { name = "jhadf", surname = "Chludzhadfi", begin = "Dhad:14", end = "Dzisiajah", price = "240 zł", remain = "42 minuty"});
        obMainListBinding.ItemTemplate = (DataTemplate)this.FindResource("BasicTransactionTemplate");
        obMainListBinding.ItemsSource = transactions;

    }

    public class Transaction
    {
        public string name { get; set; }
        public string surname { get; set; }
        public string begin { get; set; }
        public string end { get; set; }
        public string remain { get; set; }
        public string price { get; set; }
        public List<TransactionItem> items { get; set; }
    }

    public class TransactionItem
    {
        public string category { get; set; }
        public string index { get; set; }
        public string name { get;set; }
    }

    public class LessTransaction
    {
        public string name { get; set; }
        public string surname { get; set; }
        public string begin { get; set; }
        public string end { get; set; }
        public string remain { get; set; }
        public string price { get; set; }
    }

}

XAML:

<Window
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008" xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" mc:Ignorable="d" x:Class="SurfManager.MainWindow"
Title="MainWindow" Height="524.5" Width="1078">
<Window.Triggers>
    <EventTrigger RoutedEvent="FrameworkElement.Loaded"/>
</Window.Triggers>
<Window.Resources>
    <DataTemplate x:Key="BasicTransactionTemplate">
        <Grid MaxHeight="50">
            <Grid.RowDefinitions>
                <RowDefinition Height="41*"/>
                <RowDefinition Height="42*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0*"/>
                <ColumnDefinition Width="192*"/>
                <ColumnDefinition Width="234*"/>
                <ColumnDefinition Width="189*"/>
                <ColumnDefinition Width="443*"/>
            </Grid.ColumnDefinitions>
            <Label Name="Name" Content="{Binding name}" Grid.RowSpan="1" Grid.Column="1" Grid.ColumnSpan="1" />
            <Label Name="Surname" Content="{Binding surname}"  Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="1"/>
            <Label Name="Begin" Content="{Binding begin}" Grid.Column="2"/>
            <Label Name="End" Content="{Binding end}" Grid.Row="1" Grid.Column="2"/>
            <Label Name="Remain" Content="{Binding remain}" Grid.Column="3"/>
            <Label Name="Price" Content="{Binding price}" Grid.Row="1" Grid.Column="3"/>
            <ListView Name="lvItems" ItemsSource="{Binding items}" Grid.Column="4" Grid.RowSpan="2">
                <ListView.ItemTemplate>
                    <DataTemplate>
                        <StackPanel Orientation="Horizontal">
                            <TextBlock Text="{Binding category}" />
                            <TextBlock Text=", Nr" />
                            <TextBlock Text="{Binding index}" />
                            <TextBlock Text="{Binding name}" />
                        </StackPanel>
                    </DataTemplate>
                </ListView.ItemTemplate>
            </ListView>
        </Grid>
    </DataTemplate>
    <DataTemplate x:Key="LessClientTemplate">
        <Grid MaxHeight="50">
            <Grid.RowDefinitions>
                <RowDefinition Height="41*"/>
                <RowDefinition Height="42*"/>
            </Grid.RowDefinitions>
            <Grid.ColumnDefinitions>
                <ColumnDefinition Width="0*"/>
                <ColumnDefinition Width="192*"/>
                <ColumnDefinition Width="234*"/>
                <ColumnDefinition Width="189*"/>
                <ColumnDefinition Width="443*"/>
            </Grid.ColumnDefinitions>
            <Label Name="Name" Content="{Binding name}" Grid.RowSpan="1" Grid.Column="1" Grid.ColumnSpan="1" />
            <Label Name="Surname" Content="{Binding surname}"  Grid.Row="1" Grid.Column="1" Grid.ColumnSpan="1"/>
            <Label Name="Begin" Content="{Binding begin}" Grid.Column="2"/>
            <Button Name="End" Content="{Binding end}" Grid.Row="1" Grid.Column="2"/>
        </Grid>
    </DataTemplate>
</Window.Resources>
<Grid>
<TabControl>
    <TabItem Header="Obecne Wypożyczenia" Background="#FFF40AFF" Foreground="Black" BorderBrush="#FF8C8E94" OpacityMask="White">
        <Grid Background="#FFE5E5E5">
            <Grid.ColumnDefinitions>
                <ColumnDefinition/>
            </Grid.ColumnDefinitions>
            <Grid.RowDefinitions>
                <RowDefinition/>
            </Grid.RowDefinitions>
            <ListView Name="obMainListBinding" BorderThickness="0" ItemTemplate="{StaticResource BasicTransactionTemplate}">
                    <ListView.Resources>
                        <Style TargetType="ListViewItem">
                            <Setter Property="Template">
                                <Setter.Value>
                                    <ControlTemplate TargetType="ListViewItem">
                                        <Border Background="{TemplateBinding Background}">
                                            <ContentPresenter />
                                        </Border>
                                    </ControlTemplate>
                                </Setter.Value>
                            </Setter>
                        </Style>
                    </ListView.Resources>
             </ListView>
        </Grid>
    </TabItem>
    <TabItem Header="Baza Klientow">
        <Grid Background="#FFE5E5E5">
                <ListView BorderThickness="0" >

                    <ListViewItem Height="66" Background="Red">
                        <Grid Background="Black" >
                            <Grid.ColumnDefinitions>
                                <ColumnDefinition Width="0*"/>
                                <ColumnDefinition Width="0*"/>
                                <ColumnDefinition Width="0*"/>
                            </Grid.ColumnDefinitions>
                            <Grid.RowDefinitions>
                                <RowDefinition Height="0*"/>
                                <RowDefinition Height="0*"/>
                                <RowDefinition Height="0*"/>
                            </Grid.RowDefinitions>
                        </Grid>
                    </ListViewItem>
                </ListView>
            </Grid>
    </TabItem>
    <TabItem Header="TabItem" HorizontalAlignment="Left" Height="35.293" VerticalAlignment="Top" Width="57.32" Margin="-2,-2,0,-13.333">
            <Button Content="Button"  Height="100" Margin="430,174,430,173"/>
        </TabItem>
</TabControl>

【问题讨论】:

  • 如果没有看到您的原始代码,我们将不知道如何对您现有的代码库进行更改。请发帖a minimal example of what needs to change,并详细说明需要修改的地方。
  • 它必须是具有不同模板的另一个项目吗?您能否不将您需要的内容封装在根据项目是否为选定项目而更改其外观的 UserControl 中,并将其托管在原始项目模板中?
  • @JimBobBennett 我不认为它会起作用,因为应用程序在实际使用中会使用相当多的内存,我希望它使用尽可能少的内存。

标签: c# wpf listview itemtemplate


【解决方案1】:

您可以尝试使用 ItemTemplateSelector 属性:

How do I use a ItemTemplateSelector together with a HeaderTemplate in a WPF ListView?

和(或)改变模板的触发器:

How to change control template from Style.Triggers

编辑

要使用 TemplateSelector,您可以在您的项目上添加一些虚拟属性(或包装它们),这样您就可以区分新项目和旧项目。

...
public Int32 Generation
{
    get ...
}

public class GenerationTypeSelector : DataTemplateSelector
  {
    public override DataTemplate SelectTemplate(object item, DependencyObject container)
    {
        var transaction = (TransactionItem)item;
        if (transaction .Generation == 0)
            return Gen0Template;
        else
            return Gen1Template;
    }
  }

【讨论】:

  • 好吧,我在寻找答案时阅读了有关 ItemTemplateSelector 的信息,但我认为这里的主要问题是我正在使用 ItemsSource 来填充 ItemView,因此当出现不同的(这个新的)对象时我无法更改模板。
  • 主要问题是您在代码隐藏文件中进行所有操作,而不是在 XAML 中。 MVVM 不是教条或通用解决方案,但您应该尝试一下。
  • 进行了一些编辑,谢谢。我在为朋友制作这个应用程序时尝试这样做,但我使用 Win Forms 有一段时间了,旧习惯很难改掉^^。此外,我在理解许多概念时仍然存在问题,所以大部分时间我都完全糊涂了。
  • 我现在遇到过并且在某种程度上也遇到过同样的困难。任何真正新的平台或技术都需要彻底改革思维。事情就是这样——一切都不可能相同。这可能令人生畏,但至少它永远不会无聊。
  • WPF 和 MVVM 有陡峭的学习曲线,但至少当你迷上它们时,WinForms 会开始显得笨拙和笨重。
猜你喜欢
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
  • 2019-10-13
  • 2018-09-06
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多