22

これを単純なテストケースに減らすことができました。を使用して、この 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>

例外メッセージは次のとおりです。

不明なメンバー 'System.Windows.Controls.TextBox.IsReadOnly' を設定できません。行番号「13」と行位置「11」。

IsReadOnlyに設定しないとTextBox、問題なく解析されます。スタイルトリガーを削除しても、うまく解析されます。

誰でもこれに光を当てることができますか?私はWPFにかなり慣れていません。

更新:
これを再現するために使用している単体テストは次のとおりです(私のPCでは失敗しています):

[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
}

更新 2:
私はもともと、PresentationFramework v4.0.30319 だけを参照していました。PresentationCore、System.Xaml、および WindowsBase への参照を追加しても効果はありません。

プロジェクトの .NET バージョンは 4 です (フル、クライアント プロファイルではありません)。

更新 3:
Arg、これは ExpressionBlend 3.0.1927.0 および XamlPadX 4 で正常に動作しXamlReader.Parse()ますXamlReader.Load()

4

4 に答える 4

9

簡単な答え、明らかにこれはバグです。回避策として、以下を使用できます。

更新、回避策 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);

回避策 1
mscorlib で True の代わりに Boolean を使用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>";

いくつかの研究の詳細..

この奇妙な問題のテストを行いました。

最初にDockPanel、Xaml での作業を含め、次のように保存しました

string xaml = XamlWriter.Save(theDockPanel);

その xaml の部分が で動作しているかどうかを確認するためだけにXamlReader.Parse、動作しました。

次に、生成された 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)
{

}

これについて何か見つけたらまた更新します..

于 2011-07-27T22:10:49.633 に答える
3

私のクライアントの 1 人が 1 回のインストールでこれを経験しました - 私自身は再現できませんでした。
私のインスタンスでは、Textプロパティは基になるビュー モデルの文字列プロパティにバインドされ、IsReadOnlyプロパティはキャメロンの最初の例のように xaml で "True" に設定されました。

この問題は、Textプロパティのモードへのバインディングを OneWay に変更することで解決されました。

<TextBox Text="{Binding SomeProperty, Mode=OneWay}" IsReadOnly="True" />
于 2012-10-05T06:35:47.767 に答える
1

XamlParser は、トリガーが定義されている System.Windows.Interactivity などの追加のアセンブリを自動的に読み込みません。Xanl を解析する前に、コードでそのアセンブリからダミー変数を宣言してみてください。または、Assembly.Load を使用してアセンブリを読み込みます。

于 2011-07-27T21:17:08.063 に答える