ItemsControl.ItemTemplateSelector在ItemsSource更新时不重新评估模板。 [英] ItemsControl.ItemTemplateSelector not re-evaluating template when ItemsSource is updated.

查看:54
本文介绍了ItemsControl.ItemTemplateSelector在ItemsSource更新时不重新评估模板。的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述


我有一组数据,我希望能够使用两个不同的模板显示如下:

I have a collection of data which I want to be able to display using two different templates as follows:

< DataTemplate  x:Key =" TemplateA">

     ...

 < ; / DataTemplate>



 < DataTemplate  x:Key =" TemplateB">

      ...

 < / DataTemplate>



< ItemsControl  ItemsSource =" {Binding  Items}" ;  ItemTemplateSelector =" {StaticResource  myTemplateSelector}" />

<DataTemplate x:Key="TemplateA">
    ...
 </DataTemplate>

 <DataTemplate x:Key="TemplateB">
    ...
 </DataTemplate>

<ItemsControl ItemsSource="{Binding Items}" ItemTemplateSelector="{StaticResource myTemplateSelector}"
/>

推荐答案

你需要强制itemscontrol从模板中重新创建一个对象,你可以通过删除项目并将其添加到observablecollection来实现。

You need to force the itemscontrol to recreate an object from a template which you can do by removing and adding an item to an observablecollection.

这是因为模板只发生一次 - 当ui得到时提交给它的一个对象。稍后更改该对象,它不是重新模板。

This is because templating only happens the once - when the ui gets an object presented to it. Change that object later and it isn't re template.

这是一段简化的标记和代码:

Here's a piece of simplified markup and code:

<Window x:Class="wpf_Templating.MainWindow"
        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"
        xmlns:local="clr-namespace:wpf_Templating"
        mc:Ignorable="d"
        Title="MainWindow" Height="350" Width="525">
    <Window.DataContext>
        <local:MainWindowViewModel/>
    </Window.DataContext>
    <Window.Resources>
        <DataTemplate  DataType="{x:Type local:TypeA}">
            <TextBlock>AAA</TextBlock>
       </DataTemplate>
        <DataTemplate DataType="{x:Type local:TypeB}">
            <TextBlock>B B B</TextBlock>
       </DataTemplate>
    </Window.Resources>
    <Grid>
        <Grid.RowDefinitions>
            <RowDefinition Height="30"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Content="Substitute" Command="{Binding SubstituteCommand}"/>
        <ListBox ItemsSource="{Binding Objects}"
                 SelectedItem="{Binding SelectedRow, Mode=TwoWay}"
                 Grid.Row="1" />
    </Grid>
</Window>

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using GalaSoft.MvvmLight;
using GalaSoft.MvvmLight.CommandWpf;
using System.Collections.ObjectModel;

namespace wpf_Templating
{
    public class MainWindowViewModel : ViewModelBase
    {
        public ObservableCollection<object> Objects { get; set; } =
            new ObservableCollection<object> { new TypeA(), new TypeA(), new TypeB() };
        private RelayCommand _substituteCommand;

        private object _selectedRow;

        public object SelectedRow
        {
            get { return _selectedRow; }
            set { _selectedRow = value;  RaisePropertyChanged(); }
        }


        public RelayCommand SubstituteCommand
        {
            get
            {
                return _substituteCommand
                ?? (_substituteCommand = new RelayCommand(
                () =>
                {
                    if(SelectedRow !=null)
                    {
                        int ix = Objects.IndexOf(SelectedRow);

                        Object newRow;
                        if(SelectedRow.GetType() == typeof(TypeA))
                        {
                            newRow = new TypeB();
                        }
                        else
                        {
                             newRow = new TypeA();
                        }
                        Objects.Remove(SelectedRow);
                        Objects.Insert(ix, newRow);
                        SelectedRow = newRow;
                  }
                }));
            }
        }
    }
}

因为我从有效的集合中删除了该项目。

Because I remove the item from the collection that works.

如果我注释掉行

                     //   Objects.Remove(SelectedRow);
                     //   Objects.Insert(ix, newRow);


然后我正在更改对象SelectRow,它将更改集合中的项目但是ui将不会重新该项目的模板。

Then I'm changing the object SelectRow which will change the item in the collection BUT the ui won't re-template that item.


这篇关于ItemsControl.ItemTemplateSelector在ItemsSource更新时不重新评估模板。的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
相关文章
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆