2

以下は2つのxamlスニペットです。唯一の違いは、1つの例がウィンドウのビジュアルツリーに直接入力され、もう1つの例がDataContextデータテンプレートを適用して同じウィンドウを構築することです。

ビジュアルツリーコンテンツ/DataContext

<Window>
    <Window.DataContext>
        <local:MyType />
    </Window.DataContext>

    <DockPanel>
        <DockPanel.CommandBindings>
            <CommandBinding Command="ApplicationCommands.New"
                            CanExecute="OnCanExecuteNew"
                            Executed="OnExecuteNew"
                            />
        </DockPanel.CommandBindings>
        <ToolBarTray DockPanel.Dock="Top">
            <ToolBar>
                <Button Command="ApplicationCommands.New"
                        Content="New"
                        />
            </ToolBar>
        </ToolBarTray>
        <ContentPresenter Content="{Binding SomeProperty}" />
    </DockPanel>
</Window>

ビジネスオブジェクトのコンテンツとデータテンプレート

<Window>
    <Window.Resources>
        <DataTemplate DataType="{x:Type local:MyType}">
            <DockPanel>
                <DockPanel.CommandBindings>
                    <CommandBinding Command="ApplicationCommands.New"
                                    CanExecute="OnCanExecuteNew"
                                    Executed="OnExecuteNew"
                                    />
                </DockPanel.CommandBindings>
                <ToolBarTray DockPanel.Dock="Top">
                    <ToolBar>
                        <Button Command="ApplicationCommands.New"
                                Content="New"
                                />
                    </ToolBar>
                </ToolBarTray>
                <ContentPresenter Content="{Binding SomeProperty}" />
            </DockPanel>
        </DataTemplate>
    </Window.Resources>
    <Window.Content>
        <local:MyType />
    </Window.Content>
</Window>

最初の例(ビジュアルツリーコンテンツとデータコンテキスト)は、デザイナーが2番目の例でコンパイル時エラーを発生させている間は期待どおりに機能します。デリゲートタイプ。「デザイナエラーにもかかわらず、ルーティングされたコマンドハンドラが実行されていることを確認した場所で、アプリケーションをローカルで実行する場合があります。他のPCでアプリケーションを実行しようとすると、アプリケーションは起動時にサイレントに失敗し、Windowsイベントログにxamlロードエラーログエントリが残ります。2番目のスニペットからコマンドバインディングを削除すると、デザイナーエラーがなくなり、アプリケーションはローカルと他のPCの両方で問題なく実行されます。

誰かが例外の原因と、テンプレート内でコマンドバインディングを指定する方法を説明してください。

4

1 に答える 1

2

Designer(VS2010 SP1ターゲットフレームワーク.NET4.0)で次のエラーで再現できます が、アプリケーションをビルドでき、ローカルマシンで動作します。 ここでは、デザイナーはWPFランタイムとは異なる方法で作業していると思います。テンプレートがデザイン時に適用され、CommandBindingのイベントハンドラーが解決された場合、結果として得られるテンプレートのビジュアルツリーは、ウィンドウのビジュアルツリーの一部ではありません。そのため、ハンドラーを解決できません。回避策として、次のオプションを検討します。 1)CommandBindingsをウィンドウに配置します System.Windows.Markup.XamlParseException: Failed to create a 'CanExecute' from the text 'OnCanExecuteNew'
System.ArgumentException: Error binding to target method.



<Window.CommandBindings>
    <CommandBinding Command="ApplicationCommands.New"
                    CanExecute="OnCanExecuteNew"
                    Executed="OnExecuteNew"/>
</Window.CommandBindings>

2)UserControlでデータテンプレートのコンテンツをラップし、そのコードビハインドにイベントハンドラーを配置します。

UserControl.xaml

<UserControl x:Class="WpfApplication1.UserControl1">
    <DockPanel>
        <DockPanel.CommandBindings>
            <CommandBinding Command="ApplicationCommands.New"
                            CanExecute="OnCanExecuteNew"
                            Executed="OnExecuteNew"/>
        </DockPanel.CommandBindings>
        <ToolBarTray DockPanel.Dock="Top">
            <ToolBar>
                <Button Command="ApplicationCommands.New" Content="New"/>
            </ToolBar>
        </ToolBarTray>
        <ContentPresenter Content="{Binding SomeProperty}" />
    </DockPanel>
</UserControl>

Window.xaml

<DataTemplate DataType="{x:Type local:MyType}">
    <local:UserControl1/>
</DataTemplate>

3)CommandBindingsをまったく使用せず、コマンドオブジェクトをビューモデル(MVVM)に配置します。

<Button Command="{Binding NewCommand}" Content="New"/>

原則として、データテンプレートとコードビハインドの緊密な結合を避けることをお勧めします。データテンプレートは、リソースディクショナリに入れて入れるものでなければなりません。

于 2012-11-21T14:35:00.337 に答える