web-dev-qa-db-ja.com

コンポーネントには、URIで識別されるリソースがありません

すべてのビュー/ユーザーコントロールで使用する汎用DataGridを作成します。

これは私の構造です:

_Class Library_と呼ばれる_"Core"_:

Classは_"ViewBase"_と呼ばれます:

_public class ViewBase : UserControl
{
    public ViewBase()
    {
    }   

    //Rest of Methods and Properties
}
_

_Class Library_と呼ばれる_"Controls"_:

UserControl _"GridView"_の呼び出し:

XAML:

_    <vb:ViewBase x:Class="Controls.GridView"
             xmlns="http://schemas.Microsoft.com/winfx/2006/xaml/presentation"
             xmlns:x="http://schemas.Microsoft.com/winfx/2006/xaml"
             xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006" 
             xmlns:vb="clr-namespace:Core;Assembly=Core">

    <Grid>
        <DataGrid></DataGrid>
    </Grid>

    </vb:ViewBase>
_

コードビハインド:

_using Core;

public partial class GridView : ViewBase
{
    public GridView ()
    {
        InitializeComponent();
    }
}
_

次に、「WPFApp」と呼ばれるWPFアプリケーションがあります。

Classは_"View"_と呼ばれます:

_using Controls;

public class View : GridView
{
    public View()
    {
        InitializeComponent();
    }
}
_

私の全体的なアイデアは、GridViewが必要な場所でDataGridを使用することです。

アプリケーションを実行すると、次のエラーが表示されます。

_"The component 'WpfApp.View' does not have a resource identified by the URI '/Controls;component/GridView.xaml'."
_

何が間違っていますか?

これは正しいアプローチですか?

40
Willem

似たようなことをしていて、同じ結果になりました。 UsageControl(xamlに付属するxaml.csファイル)というWPFコントロールを含むC#クラスライブラリが1つありました。別のC#プロジェクト(つまり、別のdll)で、C#を作成しましたclass CPUUsageControl which inherited UsageControlから、独自のスピンをその上に置きます。ビューの1つでCpuUsageControlを使用しようとしたときに、同じエラーが発生しました。

それを修正するために行ったのは、別のアセンブリで、ベースコントロールから継承するクラスを作成する代わりに、containedベースコントロールである新しいWPFコントロールを作成したことです。次に、CpuUsageクラスに含まれていたすべてのロジックを、WpfCpuUsageControlのコードビハインドに入れました。このオブジェクトを使用できたのは、他のすべてのコントロールで十分です。

コントロール "GridView"の場合、新しいWPFユーザーコントロールを作成し、GridViewを呼び出して、グリッドコントロールのコンテンツとしてcontain "ViewBase"にします。次のように、DataGridに配置されたViewBaseのコンテンツ:

<UserControl....>
    <Grid>
        <ViewBase name="vBase">
            <DataGrid name="dGrid" />
        </ViewBase>
    </Grid>
</UserControl>

また、UserControlから直接継承するためにViewBaseが必要であることも明らかではありません。コントロールに特定のプロパティとメソッドを持たせて、BaseControlクラス(オブジェクト以外からは継承しない)を作成し、将来のコントロールに継承させるだけでよい場合。おそらく、抽象的な基本クラスまたはインターフェースがあなたの望みです。

MVVM WPFプロジェクトの場合、通常はINotifyPropertyChangedを実装するBaseViewModelがあるため、どこでも同じコードを実行する必要はありません。

幸運なことに、この問題は把握するのが非常に苦痛でした。例外メッセージとgoogleは最も役に立ちません!

11

イライラして、私はまさにこのエラーがあり、原因を突き止めるために永遠に費やしました。私にとっては、かつては機能していましたが、派生コントロールのXAMLに非常に小さな変更を加えると、コンパイラーがそのエラーメッセージを出し始めました。短い解決策、それを理解するのに何時間も費やすことを省きます:Visual Studioをシャットダウンし、再度開き、再コンパイルし、問題は魔法のように消えました! (これはVS2012 Proです)読んでいる人が自分のコードに存在しない問題を見つけようと円を描くようになった場合にこれを追加しました。 「IT Crowdソリューション」を最初に試す価値があるかもしれません。

58
HughHughTeotl

このエラーが発生する理由は、VS 2010で実装されたInitializeComponentが常に派生クラスのアセンブリを検索するためです。

InitializeComponentは次のとおりです。

/// <summary>
/// InitializeComponent
/// </summary>
[System.Diagnostics.DebuggerNonUserCodeAttribute()]
[System.CodeDom.Compiler.GeneratedCodeAttribute("PresentationBuildTasks", "4.0.0.0")]
public void InitializeComponent() {
    if (_contentLoaded) {
        return;
    }
    _contentLoaded = true;
    System.Uri resourceLocater = new System.Uri("/WpfApplication1;component/mainwindow.xaml", System.UriKind.Relative);

    #line 1 "..\..\..\MainWindow.xaml"
    System.Windows.Application.LoadComponent(this, resourceLocater);

    #line default
    #line hidden
}

XAMLリソースを検索する行はSystem.Windows.Application.LoadComponent(this、resourceLocator)です。そして、 'this.GetType()。Assembly'に相当するものを使用して、相対Uriで識別されるリソースを検索するアセンブリを決定するため、これはおそらく失敗します。また、「this.GetType()」は、コードが実装されているクラスのタイプではなく、オブジェクトの派生タイプを取得します。

PS。これはバグですか?私は知らない...

21

これで3日間頭痛がしました!クラスライブラリにXAML UserControlがあり、.exeプロジェクトのUserControlから派生したクラス(C#のみ)があります。 MainWindow.xamlのxamlデザイナーで、アプリケーションを起動すると、「コンポーネントにはURIで識別されるリソースがありません」というエラーが表示されました。 「Juan CarlosGirón」の答えがついに私を解決へと導きました。

using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;

using System.Windows;
using System.Windows.Controls;
using System.Windows.Navigation;
using System.Reflection;
using System.IO.Packaging;
using System.Windows.Markup;

namespace ClassLibrary1
{
    static class Extension
    {
        public static void LoadViewFromUri(this UserControl userControl, string baseUri)
        {
            try
            {
                var resourceLocater = new Uri(baseUri, UriKind.Relative);
                var exprCa = (PackagePart)typeof(Application).GetMethod("GetResourceOrContentPart", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { resourceLocater });
                var stream = exprCa.GetStream();
                var uri = new Uri((Uri)typeof(BaseUriHelper).GetProperty("PackAppBaseUri", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null), resourceLocater);
                var parserContext = new ParserContext
                {
                    BaseUri = uri
                };
                typeof(XamlReader).GetMethod("LoadBaml", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { stream, parserContext, userControl, true });
            }
            catch (Exception)
            {
                //log
            }
        }
    }
}

userControlの.csファイルから呼び出しました:

namespace ClassLibrary1
{
    public partial class MyUserControl : UserControl
    {
        public MyUserControl()
        {
            //InitializeComponent();
            this.LoadViewFromUri("/ClassLibrary1;component/myusercontrol.xaml");
        }
    }
}

「Juan CarlosGirón」に再び感謝します!

19
PainElemental

このアプローチを試すことができます

独自のInitializeComponent()を作成し、この方法で呼び出しました

this.LoadViewFromUri("/NameOfProject;component/mainwindow.xaml");


public static void LoadViewFromUri(this Window window, string baseUri)
    {
        try
        {
            var resourceLocater = new Uri(baseUri, UriKind.Relative);
            var exprCa = (PackagePart)typeof(Application).GetMethod("GetResourceOrContentPart", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { resourceLocater });
            var stream = exprCa.GetStream();
            var uri = new Uri((Uri)typeof(BaseUriHelper).GetProperty("PackAppBaseUri", BindingFlags.Static | BindingFlags.NonPublic).GetValue(null, null), resourceLocater);
            var parserContext = new ParserContext
            {
                BaseUri = uri
            };
            typeof(XamlReader).GetMethod("LoadBaml", BindingFlags.NonPublic | BindingFlags.Static).Invoke(null, new object[] { stream, parserContext, window, true });

        }
        catch (Exception)
        {
            //log
        }
    }
10

ここで同じ問題。

短縮版:

Copy LocalFalseに設定する必要があります!

ロングバージョン:

WPFソリューション(MVVM、20プロジェクト)を開発し、プラグインシステムを実装しました。/bin/Debugディレクトリには、実行可能ファイル、いくつかのdllファイル、およびプラグインを含むプラグインディレクトリが含まれています。ウィンドウ(ビュー)、ViewModel、Model、およびいくつかのインターフェースを定義するプロジェクト「DialogLib」(クラスライブラリ、ダイアログの一種)があります。プラグインの1つがDialogLibのインターフェイスの1つを使用しました。ウィンドウ自体は、メインアプリケーションによって開かれます。

プラグインで「DialogLib」ライブラリのインターフェイスを使用するには、DialogLibのプロジェクト参照をプラグインプロジェクト参照に追加する必要がありました。アプリケーションの起動時に、プラグインがロードされました。ユーザーがメニュー項目を選択すると、ウィンドウが開きます。この時点で、WindowsコードビハインドがそのInitializeComponent()を実行しようとしたときに、「...コンポーネントにはURIで識別されるリソースがありません...」というエラーが発生しました。

問題はどこにありますか?

問題は、VSがDialogLib.dllを正しく作成し、それを/ bin/Debug /にコピーしたソリューションを構築したことです。これは、メインアプリケーションファイルがウィンドウを開きたいためです。ただし、DialogLib.dllは、DialogLib.dllで定義されたインターフェイスの1つを使用するためにプラグインの1つが参照するため、/ bin/Debug/pluginsにもコピーされました。だから何?

プラグインが実行時にロードされるとき、/ bin/Debug/plugins/DialogLib.dllで定義されたインターフェースを使用します。メインアプリケーションファイルは、/ bin/Debug/DialogLib.dllで定義されているウィンドウを開こうとします。ファイルは同一ですが、VSで問題が発生します。プラグイン参照のDialogLib参照プロパティのCopy Localの値を設定すると、DialogLib.dllを/ bin/Debug/pluginsにコピーすることを回避し、問題を解決します。 。

Dllファイルで定義されたタイプTypeAを使用したい別のプロジェクトで同様の問題(エラーは異なります)がありました。プラグインおよびメインアプリケーション内。 Copy Localtrueに設定され、dllファイルのコピーが発生した../ bin/Debug/pluginsおよび../ bin/Debug /。同じdllファイルであっても、メインアプリファイルのTypeATypeA プラグインでは、交換できないタイプとしてそれぞれ異なるタイプとして扱われました。

8
ooorndtski

配置することでこれを解決しました

_myusercontrol = Activator.CreateInstance<myusercontrol>(); 
_

InitializeComponent();行の前にusercontrolを含むウィンドウのコンストラクター内

6
Darren
  • objフォルダーを削除
  • binフォルダーを削除
  • 再構築ソリューション

私のために働いた!

また、_Assembly.LoadFile_を使用してアセンブリをロードする場合は、現在のAppDomainに重複するアセンブリがないかAppDomain.CurrentDomain.GetAssemblies()を確認してください。 WPF UserControlの自動生成コードでは、コンポーネントはその相対URIを使用してロードされるためです。また、現在のAppDomainには重複したアセンブリがあるため、アプリケーションはどのアセンブリを使用するかを知りません。

6
VahidN

Visual Studio 2013の使用時に同じエラーを受け取りました。

コンポーネントには、URIで識別されるリソースがありません

試行:
ソリューションのクリーニングと再構築-動作しませんでした。
Visual Studioを閉じて開く-動作しませんでした。

解決策:
projects binディレクトリに移動し、すべてのファイルを消去しました。
プロジェクトを再度実行し、正常に動作しました。

パッケージマネージャーコンソールを開き、ソリューションのルートディレクトリで開き、次のPowerShellコマンドを実行します。

Get-ChildItem -inc bin,obj -recurse | Remove-Item -recurse -force -EA SilentlyContinue
5
Ralph Willgoss

私が同じプロジェクトを2つのソリューションで開いたときに、私に起こります。 1つのプロジェクトのベースコントロールを変更すると、他のプロジェクトでこの問題が発生します。閉じたり開いたりできない場合は、「C:\ Users ...\AppData\Local\Microsoft\VisualStudio\12.0\Designer\ShadowCache」にあるすべてのフォルダーを削除してください

1
AMissico

@Willem、これは私にはまったく問題ないようです。実際、私はこれを試しましたが、私の場合はうまくいきました。 ListBoxの代わりにDataGridを使用しました(しかし、それは問題ではありません)。

名前空間はすべて1つのアセンブリに含まれていました。だから私はすべてのために共通の親名前空間を使用しました.

MyWpfApplication.ControlsMyWpfApplciation.GridViewMyWpfApplciation.ViewBase

これらのControlsGridViewViewBaseはすべて、既存のSystemまたはSystem.Windows.Controlsベースの名前空間およびクラス宣言。そこで、正しいものを参照したことを確認しましたMyWpfApplication.*私のプロジェクト。

1
WPF-it

これは、closeing and reopeningウィンドウの場合にも発生する可能性があります。そのため、パッケージやdllとは関係ありません。
PainElementalが投稿したソリューションのおかげで問題を解決しました。

namespace MyNamespace
{
  public partial class MyDialog : Window
  {
    public MyDialog(ExcelReference sheetReference)
      {
        this.LoadViewFromUri("/MyApp;component/mynamespace/mydialog.xaml");
      }
  }
}

PainElementalが書いたように、LoadViewFromUriは拡張機能として実装されます。最もクレイジーなのは、同じプロジェクトで他のウィンドウを問題なく表示したことです。
PainElemental、ありがとう、私の長引く痛みを終わらせました!

1
Mauro

Xamlファイルの名前を変更すると、このエラーが発生しました。名前の変更を元に戻すと、問題は解決しました。

さらに、App.xamlのxamlファイル名への参照は更新されていないことがわかりました(StartupUri)が、現在の名前に名前を変更しても問題は解決しませんでした(ただし、おそらく解決します)。基本的に、xamlファイルの名前は変更できません。

Fyi、私にとって、エラーの「不平を言っている」コンポーネントはSplitComboBoxでした。

1
JBSnorro

誤って削除済み名前変更/コピーアクションを介したユーザーコントロールがありました。バージョンコントロールからプロジェクトファイルとxamlファイルと.csを復元すると、誤って削除/名前変更されたコントロールのデザインスタジオでこのエラーが発生し始めました。

それは、問題のファイルに何らかのタイプのキャッシュを提案しました。..Visual Studioを閉じ、binディレクトリを削除して、再構築が機能しました。

0
ΩmegaMan

すべてのVisual Studioを閉じるよりも、タスクマネージャーでXDescProc.exeを終了するだけです。

XDescProcはデザイナーです。プロセスが終了すると、Visual Studioに[デザイナーの再読み込み]リンクが表示されます。それをクリックすると、XDesが再び開始され、「リソースなし」エラーがなくなるはずです。

これは、デザイナープロセスを終了した後のVisual Studioのリンクです。

enter image description here

0
Bill Tarbell

PainElementalのソリューションに従いました(明確にするために、彼のコードではClassLibrary1は拡張子が.dllのない.dllでした)、特定のエラーメッセージを問題にリンクするのに役立つ場合の私のシナリオは次のとおりです:

Dllを使用して、ユーザーコントロールをメインプログラムに独自のポップアップウィンドウとして読み込んで実行します。 PainElementalのソリューションはほとんど機能していましたが、私の "popup .dll"の3つのクラスのうち1つは正しくロードされませんでした。次のような2つの内部例外で例外が発生します。

mscorlib InvokeMethod ...;
WpfXamlLoader.Load ... StaticResourceExtensionに値を提供...;
ResolveBamlType ....メソッドまたは操作は実装されていません。

私の場合、新しいURIをロードしてテストすることを確認しましたが、Live環境で実行しようとすると、LoadViewFromUri()でエラーが発生しました。

さらにテストするにつれて、問題を絞り込んで、失敗したクラスの.xamlファイルで使用していたコンバーターを含む別の「library .dll」ファイルをロードできないようにしました。問題は、「popup .dll」からの例外メッセージはそれについて言及していなかったにもかかわらず、Live環境がテスト環境で使用していたものとは異なる「library .dll」バージョンを使用していたことでした。

参考として、Copy Local = Trueを使用しますが、問題はありませんでした。この種の問題をデバッグするには、.dllファイルが.exeで検索される場所を理解しておくと役立ちます。私が理解しているように、VSでプロジェクトを実行しているとき、Copy Local = Trueのとき、.dllはビルド時に.exeと同じフォルダにコピーされます。 .exeが標準の場所で実行されると、.dllが.exeと同じフォルダにあることを検索します。 .exeが.dllを検索できる追加の場所は、プローブ要素の.exe.configファイルで設定できます。次の例では、.exeの場所に関連する「MyDLLs」および「MyDLLs\Core」ディレクトリも検索できます。サブフォルダーは自然には検索されないため、明示的に指定する必要があります。 GACも検索すると思いますが、現在GACに関する知識はほとんどありません。

<configuration>
 ... 

   <runtime>  
      <assemblyBinding xmlns="urn:schemas-Microsoft-com:asm.v1">
         <probing privatePath="MyDLLs;MyDLLs\Core;"/>
      </assemblyBinding>
   </runtime>  
</configuration>
0
DeltaPng

継承の問題もなく、この問題に遭遇しました。ダイアログを含むDLLを参照し、そのダイアログを作成して表示しようとしました。特定のフォルダーからアセンブリを読み込むアセンブリリゾルバーがあり、参照を追加したことがわかりましたVSとローカルコピーをオフにしていませんでした。簡単に言えば、私のプロセスは同じDLLの2つのバージョンをロードしました。これはWPF(またはランタイム)を混乱させるようです。ローカルコピーをクリアして余分なDLLコピー、再び正常に動作しました。

0
Clutchplate