Cam*_*ron 22 c# wpf xaml xamlreader
我已经设法将其简化为一个简单的测试用例.在使用以下方法解析此XAML期间抛出异常XamlReader.Parse():
<DockPanel xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<DockPanel.Resources>
<Style TargetType="TextBox">
<Style.Triggers>
<Trigger Property="IsReadOnly" Value="True">
<Setter Property="Background" Value="#FFEEEEEE" />
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Resources>
<TextBox IsReadOnly="True" />
</DockPanel>
Run Code Online (Sandbox Code Playgroud)
异常消息是:
无法设置未知成员'System.Windows.Controls.TextBox.IsReadOnly'.行号'13'和行位置'11'.
如果我不设置IsReadOnly上TextBox,它解析罚款.如果我删除样式触发器,它也会解析.
任何人都可以对此有所了解吗?我对WPF很新.
更新:
这是我用来重现这个的单元测试(它在我的电脑上失败了):
[TestMethod]
public void TestIsReadOnlyOnTextBox()
{
// Arrange
var xaml =
@"<DockPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation"" xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<DockPanel.Resources>
<Style TargetType=""TextBox"">
<Style.Triggers>
<Trigger Property=""IsReadOnly"" Value=""True"">
<Setter Property=""Background"" Value=""#FFEEEEEE"" />
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Resources>
<TextBox IsReadOnly=""True"" />
</DockPanel>
";
// Act
try {
var root = XamlReader.Parse(xaml);
}
catch (XamlParseException ex) {
Assert.Fail(ex.Message);
}
// If we get here, test passes
}
Run Code Online (Sandbox Code Playgroud)
更新2:
我最初只是引用PresentationFramework v4.0.30319.添加对PresentationCore,System.Xaml和WindowsBase的引用无效.
.NET版本的项目是4(完整,而不是客户端配置文件).
更新3:
Arg,这在ExpressionBlend 3.0.1927.0和XamlPadX 4中运行良好.正如AresAvatar报道的那样,它似乎只有在用XamlReader.Parse()或解析时才会失败XamlReader.Load()!
简短的回答,显然这是一个错误.以下内容可用作解决方法.
更新,解决方法2
即使只是在XamlReader.Parse(xaml)修复问题之前执行以下行,仍然无法解释为什么虽然..
XamlReader.Parse(@"<TextBox xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
IsReadOnly=""True""/>");
var root = XamlReader.Parse(xaml);
Run Code Online (Sandbox Code Playgroud)
解决方法1
在mscorlib中使用布尔而不是True Trigger似乎可以解决问题.以下xaml不会抛出异常XamlReader.Parse
var xaml =
@"<DockPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml""
xmlns:s=""clr-namespace:System;assembly=mscorlib"" >
<DockPanel.Resources>
<s:Boolean x:Key=""BooleanTrue"">True</s:Boolean>
<Style TargetType=""TextBox"">
<Style.Triggers>
<Trigger Property=""IsReadOnly"" Value=""{StaticResource BooleanTrue}"">
<Setter Property=""Background"" Value=""#FFEEEEEE"" />
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Resources>
<TextBox IsReadOnly=""True"" />
</DockPanel>";
Run Code Online (Sandbox Code Playgroud)
一些研究细节......
我对这个奇怪的问题做了一些测试.
首先,我将工作包括DockPanel在Xaml中并保存
string xaml = XamlWriter.Save(theDockPanel);
Run Code Online (Sandbox Code Playgroud)
只是为了看看那片xaml是否正在使用XamlReader.Parse,它确实如此.
然后我对生成的xaml进行了小的更改(并在异常返回后恢复),直到我尽可能接近原始xaml.奇怪的是,一旦解析了这个xaml,原始的也可以工作.
使其工作的部分似乎是使用<s:Boolean>True</s:Boolean>而不是True.
var modifiedXaml = @"<DockPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:s=""clr-namespace:System;assembly=mscorlib""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<DockPanel.Resources>
<s:Boolean x:Key=""BooleanTrue"">True</s:Boolean>
<Style TargetType=""TextBox"">
<Style.Triggers>
<Trigger Property=""IsReadOnly"" Value=""{StaticResource BooleanTrue}"">
<Setter Property=""Background"" Value=""#FFEEEEEE"" />
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Resources>
<TextBox IsReadOnly=""True"" />
</DockPanel>";
var originalXaml = @"<DockPanel xmlns=""http://schemas.microsoft.com/winfx/2006/xaml/presentation""
xmlns:x=""http://schemas.microsoft.com/winfx/2006/xaml"">
<DockPanel.Resources>
<Style TargetType=""TextBox"">
<Style.Triggers>
<Trigger Property=""IsReadOnly"" Value=""True"">
<Setter Property=""Background"" Value=""#FFEEEEEE"" />
</Trigger>
</Style.Triggers>
</Style>
</DockPanel.Resources>
<TextBox IsReadOnly=""{Binding}""/>
</DockPanel>";
try
{
// If this line is executed, no `XamlParseException` is thrown
var root = XamlReader.Parse(modifiedXaml);
var root2 = XamlReader.Parse(originalXaml);
}
catch (XamlParseException ex)
{
}
Run Code Online (Sandbox Code Playgroud)
如果我发现更多内容,我会再次更新..
| 归档时间: |
|
| 查看次数: |
5934 次 |
| 最近记录: |