我从事 WPF 开发大约有 10 年了,见过各种各样的愚蠢行为,但今天我偶然发现了一批新鲜的公牛粪便,绝对……
我从事 WPF 开发已经有 10 年了,见过很多 各种各样 的愚蠢行为,但今天我偶然发现了一批新鲜的雄性牛粪,它们绝对是最愚蠢的。事实上,是所有存在的愚蠢行为。
将转换器放在窗口资源列表的顶部会以某种方式破坏其后的 UI 对象的资源。
下面是重现此问题的最简单的应用程序示例,其中包含我能找到的最少的代码:
<Window x:Class="WpfApp1.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:converters="clr-namespace:WpfApp1.Converters"
xmlns:system="clr-namespace:System;assembly=mscorlib"
SizeToContent="WidthAndHeight"
WindowStartupLocation="CenterScreen">
<Window.Resources>
<converters:BaseConverter x:Key="test"/>
<Grid x:Key="TestItemTemplateGrid" x:Shared="false">
<Button Content="{Binding StringFormat='Button {0}'}" Width="300"/>
</Grid>
</Window.Resources>
<ItemsControl>
<system:Int32>0</system:Int32>
<system:Int32>1</system:Int32>
<system:Int32>2</system:Int32>
<system:Int32>3</system:Int32>
<ItemsControl.ItemTemplate>
<DataTemplate>
<ContentControl Content="{StaticResource TestItemTemplateGrid}" Margin="0,5,0,0"/>
</DataTemplate>
</ItemsControl.ItemTemplate>
</ItemsControl>
</Window>
转换器:
using System;
using System.Globalization;
using System.Windows.Data;
using System.Windows.Markup;
namespace WpfApp1.Converters
{
public class BaseConverter : MarkupExtension, IValueConverter
{
public virtual object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
public virtual object ConvertBack(object value, Type targetType, object parameter, CultureInfo culture)
{
return Binding.DoNothing;
}
public override object ProvideValue(IServiceProvider serviceProvider)
{
return this;
}
}
}
这只是一个简单的尝试,在 ItemsControl 中加载可变数量的项目,其中每个项目都是一个 ContentControl,它将自身填充为资源中定义的 Grid。
根据此 xaml, 应用程序 应该
但实际上它看起来是这样的:
这就像 x:Shared 被打破并变成现实或者别的什么,只是因为在它之前有一个转换器资源。
我测试过的内容:
-
转换器的键名并不重要
-
转换器的类型和/或方法实现并不重要
-
ItemsControl 是否具有绑定的 ItemsSource 与硬编码条目无关紧要
-
网格内的实际内容并不重要
当然,删除 <converters:BaseConverter x:Key="test"/>
可以修复该问题,但真正的问题是: 将其放在资源列表的最后也可以修复该问题。
...哇。哇。 是 ?我死了吗?我在做梦吗?愚人节是被编入 WPF 的吗,但它有 bug(就像其他东西一样)而且晚了一个月?有人能解释一下吗?我快疯了。
项目文件(以防万一):
<Project Sdk="Microsoft.NET.Sdk">
<PropertyGroup>
<OutputType>WinExe</OutputType>
<TargetFramework>net5.0-windows</TargetFramework>
<UseWPF>true</UseWPF>
</PropertyGroup>
</Project>