XAML TemplateSelector 似乎有点延迟
XAML TemplateSelector seems kind of delayed
目前我正面临一个非常奇怪的问题。我的模板选择器似乎有点延迟。
对我当前情况的粗略描述,我正在开发一个简单的 UWP 应用程序,该应用程序具有嵌套列表视图以显示按固定属性分组的一些项目。这些项目应该可以通过将视图从“ViewMode”切换到“EditMode”来编辑。通过启用“EditView”,第一个 ListView 不会更新为 EditView 模板...?!但为什么?我制作了一个完整的演示示例,其中包括视图用户控件、主页和演示模型 类,如下所示(github 上的完整演示:https://github.com/tzdlr/SODemo):
UWP 页面:
<Page
x:Class="UWPTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<CommandBar Grid.Row="0">
<AppBarToggleButton Icon="Edit" Label="Bearbeitungs-Ansicht" IsChecked="{x:Bind EditMode, Mode=TwoWay}" />
</CommandBar>
<local:ListViewControl Grid.Row="1" MyListCollection="{x:Bind MyList}"></local:ListViewControl>
</Grid>
</Page>
UWP 用户控件
<UserControl
x:Class="UWPTest.ListViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<DataTemplate x:Key="DTView" x:DataType="local:Model">
<Grid>
<TextBlock Text="{x:Bind Text}"></TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DTEdit" x:DataType="local:Model">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{x:Bind Text,Mode=TwoWay}"></TextBox>
<Button Grid.Column="1" Content="Delete"></Button>
</Grid>
</DataTemplate>
<local:ModelSelector x:Key="tplSelector"
ViewTemplate="{StaticResource DTView}"
EditTemplate="{StaticResource DTEdit}" />
</UserControl.Resources>
<ListView x:Name="list" ItemsSource="{x:Bind MyListCollection, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:ListModel">
<ListView ItemsSource="{x:Bind ModelList,Mode=TwoWay}" ItemTemplateSelector="{StaticResource tplSelector}"></ListView>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</UserControl>
我的模型和其他类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace UWPTest
{
public class Model
{
public string Text;
public Model(string t) { Text = t; }
}
public class ListModel
{
public List<Model> ModelList = new List<Model>();
}
public class ModelSelector : DataTemplateSelector
{
public DataTemplate ViewTemplate { get; set; }
public DataTemplate EditTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
return StaticHelper.EditView ? EditTemplate : ViewTemplate;
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return StaticHelper.EditView ? EditTemplate : ViewTemplate;
}
}
static class StaticHelper
{
public static bool EditView { get; set; } = false;
}
public class DataService
{
private List<ListModel> _cache = new List<ListModel>();
public void LoadData()
{
_cache.Clear();
for (var i = 0; i < 5; i++)
{
ListModel nl = new ListModel();
for (var k = 0; k < 10; k++)
{
nl.ModelList.Add(new Model(i + "-" + k));
}
_cache.Add(nl);
}
}
public List<ListModel> getCachedEntries()
{
return _cache;
}
}
}
这是结果,window 在“ViewMode”后面,window 在前面:“EditView”:
XAML TemplateSelector seems kind of delayed
在测试上面的代码示例时。看起来嵌套的列表视图缓存导致了这个问题。您只需清除父项目来源。但不清除嵌套。
请找到第 36 行 EditMode
设置方法调用 _ds.LoadData()
以清除嵌套
public bool EditMode
{
get { return (bool)GetValue(EditViewProperty); }
set
{
StaticHelper.EditView = value;
Task.Run(() => { _ds.LoadData(); BuildSource(); });
SetValue(EditViewProperty, value);
}
}
更新
<ListView x:Name="list" ItemsSource="{x:Bind MyListCollection, Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
......
目前我正面临一个非常奇怪的问题。我的模板选择器似乎有点延迟。
对我当前情况的粗略描述,我正在开发一个简单的 UWP 应用程序,该应用程序具有嵌套列表视图以显示按固定属性分组的一些项目。这些项目应该可以通过将视图从“ViewMode”切换到“EditMode”来编辑。通过启用“EditView”,第一个 ListView 不会更新为 EditView 模板...?!但为什么?我制作了一个完整的演示示例,其中包括视图用户控件、主页和演示模型 类,如下所示(github 上的完整演示:https://github.com/tzdlr/SODemo):
UWP 页面:
<Page
x:Class="UWPTest.MainPage"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
Background="{ThemeResource ApplicationPageBackgroundThemeBrush}">
<Grid>
<Grid.RowDefinitions>
<RowDefinition Height="auto"></RowDefinition>
<RowDefinition Height="*"></RowDefinition>
</Grid.RowDefinitions>
<CommandBar Grid.Row="0">
<AppBarToggleButton Icon="Edit" Label="Bearbeitungs-Ansicht" IsChecked="{x:Bind EditMode, Mode=TwoWay}" />
</CommandBar>
<local:ListViewControl Grid.Row="1" MyListCollection="{x:Bind MyList}"></local:ListViewControl>
</Grid>
</Page>
UWP 用户控件
<UserControl
x:Class="UWPTest.ListViewControl"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:local="using:UWPTest"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
d:DesignHeight="300"
d:DesignWidth="400">
<UserControl.Resources>
<DataTemplate x:Key="DTView" x:DataType="local:Model">
<Grid>
<TextBlock Text="{x:Bind Text}"></TextBlock>
</Grid>
</DataTemplate>
<DataTemplate x:Key="DTEdit" x:DataType="local:Model">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"></ColumnDefinition>
<ColumnDefinition Width="auto"></ColumnDefinition>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{x:Bind Text,Mode=TwoWay}"></TextBox>
<Button Grid.Column="1" Content="Delete"></Button>
</Grid>
</DataTemplate>
<local:ModelSelector x:Key="tplSelector"
ViewTemplate="{StaticResource DTView}"
EditTemplate="{StaticResource DTEdit}" />
</UserControl.Resources>
<ListView x:Name="list" ItemsSource="{x:Bind MyListCollection, Mode=TwoWay}">
<ListView.ItemTemplate>
<DataTemplate x:DataType="local:ListModel">
<ListView ItemsSource="{x:Bind ModelList,Mode=TwoWay}" ItemTemplateSelector="{StaticResource tplSelector}"></ListView>
</DataTemplate>
</ListView.ItemTemplate>
</ListView>
</UserControl>
我的模型和其他类:
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using Windows.UI.Xaml;
using Windows.UI.Xaml.Controls;
namespace UWPTest
{
public class Model
{
public string Text;
public Model(string t) { Text = t; }
}
public class ListModel
{
public List<Model> ModelList = new List<Model>();
}
public class ModelSelector : DataTemplateSelector
{
public DataTemplate ViewTemplate { get; set; }
public DataTemplate EditTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item)
{
return StaticHelper.EditView ? EditTemplate : ViewTemplate;
}
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
return StaticHelper.EditView ? EditTemplate : ViewTemplate;
}
}
static class StaticHelper
{
public static bool EditView { get; set; } = false;
}
public class DataService
{
private List<ListModel> _cache = new List<ListModel>();
public void LoadData()
{
_cache.Clear();
for (var i = 0; i < 5; i++)
{
ListModel nl = new ListModel();
for (var k = 0; k < 10; k++)
{
nl.ModelList.Add(new Model(i + "-" + k));
}
_cache.Add(nl);
}
}
public List<ListModel> getCachedEntries()
{
return _cache;
}
}
}
这是结果,window 在“ViewMode”后面,window 在前面:“EditView”:
XAML TemplateSelector seems kind of delayed
在测试上面的代码示例时。看起来嵌套的列表视图缓存导致了这个问题。您只需清除父项目来源。但不清除嵌套。
请找到第 36 行 EditMode
设置方法调用 _ds.LoadData()
以清除嵌套
public bool EditMode
{
get { return (bool)GetValue(EditViewProperty); }
set
{
StaticHelper.EditView = value;
Task.Run(() => { _ds.LoadData(); BuildSource(); });
SetValue(EditViewProperty, value);
}
}
更新
<ListView x:Name="list" ItemsSource="{x:Bind MyListCollection, Mode=TwoWay}">
<ListView.ItemsPanel>
<ItemsPanelTemplate>
<StackPanel />
</ItemsPanelTemplate>
</ListView.ItemsPanel>
......