Visual Studio 无法解析 WPF 窗口中的静态资源,即使它在运行时工作 - 为什么?

发布于 2024-11-01 09:53:42 字数 875 浏览 1 评论 0原文

我有一个 WPF 窗口并使用 MVVM 模式。我将视图模型设置为窗口的资源,如下所示...

<Window
  ...other stuff removed for clarity...
  xmlns:mvvm="clr-namespace:VisionRT.CRM.WPF.ViewModels.VRTSystems"
>
<Window.Resources>
  <mvvm:DhrTemplatesViewModel x:Key="viewmodel" />
</Window.Resources>

我想设置窗口的数据上下文以使用该资源,并发现以下 XAML 有效...

  <Window.DataContext>  
    <StaticResource ResourceKey="viewmodel"/> 
  <Window.DataContext> 

问题是我只能通过键入来完成此操作手动 XAML,Visual Studio 不会在任何地方显示资源。我可以转到窗口的属性,然后单击 DataContext 属性旁边的小图标,单击“应用资源”选项,但它不会将“viewmodel”显示为静态或动态资源。如果我手动输入 XAML,然后打开“应用资源”弹出窗口,它会在“viewmodel”下划线作为错误,并将鼠标悬停在其上显示工具提示“无法解析资源引用”

但是,当我运行应用程序时,它工作正常,因此资源正在在运行时解析。

有谁能解释一下吗?我真的很希望能够通过 VS 属性编辑器来完成此操作,因为我发现这比手动键入 XAMl 更方便。我也很烦恼VS无法解决这个问题。这让我觉得我做错了什么。

感谢您能给出的任何解释。

I have a WPF window and am using the MVVM pattern. I set the view model as a resource for the window as follows...

<Window
  ...other stuff removed for clarity...
  xmlns:mvvm="clr-namespace:VisionRT.CRM.WPF.ViewModels.VRTSystems"
>
<Window.Resources>
  <mvvm:DhrTemplatesViewModel x:Key="viewmodel" />
</Window.Resources>

I want to set the window's data context to use the resource, and found that the following XAML works...

  <Window.DataContext>  
    <StaticResource ResourceKey="viewmodel"/> 
  <Window.DataContext> 

The problem is that I can only do this by typing the XAML manually, Visual Studio doesn't show the resource anywhere. I can go to the window's properties and click the little icon next to the DataContext property, click the "Apply resource" option, but it doesn't show "viewmodel" as a resource, static or dynamic. If I enter the XAML manually and then open the "Apply resource" pop-up window, it has the "viewmodel" underlined as an error, and hovering over it shows a tooltip "cannot resolve resource reference"

However, when I run the application, it works fine, so the resource is being resolved at run time.

Anyone able to explain this? I would really like to be able to do this through the VS property editor, as I find that more convenient than typing the XAMl by hand. I'm also bothered by the fact that VS can't resolve it. This makes me think I'm doing something wrong.

Thanks for any explanation you can give.

如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。

扫码二维码加入Web技术交流群

发布评论

需要 登录 才能够评论, 你可以免费 注册 一个本站的账号。

评论(3

触ぅ动初心 2024-11-08 09:53:42

唯一(悲伤的)解释是 XAML 在 Visual Studio 中只是二等公民。一旦您开始推动 XAML 超出基本范围,您最终会遇到“未解决”“无法显示”“抱歉我很笨”等问题。

请参阅此 WPF 建议:http://dotnet.uservoice.com/forums/40583-wpf-feature-suggestions/suggestions/480899-make-xaml-a-first-class-citizen-of-visual-studio?ref= title 来修复它们。

The only (sad) explanation is that XAML is a second grade citizen in Visual Studio. Once you start pushing XAML a little more than basic and you end up with "unresolved" "cant display" "sorry I'm dumb", etc.

Refer to this WPF suggestion: http://dotnet.uservoice.com/forums/40583-wpf-feature-suggestions/suggestions/480899-make-xaml-a-first-class-citizen-of-visual-studio?ref=title to get them fixed.

时光无声 2024-11-08 09:53:42

在 Visual Studio 中,可以使 Intellisense 对于 XAML {StaticResource} 100% 工作。

上测试

  • 在WPF/C#
  • Visual Studio 2015 Update 3

第 1 步:将资源转移到共享项目中

关键是将 ResourceDictionary 引用的所有资源转移到共享项目中:

输入图像描述这里

步骤 2:设计时智能感知

我们还没有完全做到这一点。如果两次包含资源,XAML 运行时会抛出运行时错误。

如果我们在整个项目中多次包含 .xaml 文件,我们可以在设计时包含它,但不能在运行时包含它:

public class DesignTimeResourceDictionary : ResourceDictionary
{
    private Uri source;

    public new Uri Source
    {
        get
        {
            if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
            {
                return null;
            }

            return this.source;
        }
        set { this.source = value; }
    }
}

然后我们可以添加设计时资源:

<!--Design time resource dictionary, so intellisense will work with with {StaticResource}.-->
<ResourceDictionary.MergedDictionaries>
    <dr:DesignTimeResourceDictionary Source="/Project.Name;component/Folder/SharedResourceA.xaml" />
    <dr:DesignTimeResourceDictionary Source="/Project.Name;component/Folder/SharedResourceB.xaml" />
</ResourceDictionary.MergedDictionaries>

如果我们使用 ReSharper,它将自动添加标题中的命名空间前缀:

xmlns:dr="clr-namespace:MyNamespace;assembly=Project.Name"

附录 A:专家额外说明:为什么需要步骤 1?

顺便说一句,XAML 中的 Intellisense 与 C# 中的 Intellisense 相同:它仅适用于引用的子项目。这就是为什么如果项目 A 和 B 想要共享一些代码,则必须将其放在项目 A 和 B 引用的类库 C 中。这与 C 或 C++ 形成对比,在 C 或 C++ 中 #include 根目录中的文件使得它可以共享。可用于所有子文件。

使用 XAML,您可以作弊并将静态资源添加到主应用程序项目(上面)中,并且 XAML 运行时仍然可以正常工作 - 但 Intellisense 在设计时不会工作,大概是因为它基于与 C# 智能感知使用的引擎相同。

为了使 Intellisense 在 XAML 中始终工作,Visual Studio Intellisense 必须向上扫描每个父项目(而不是仅向下扫描引用的项目)。

It is possible to make Intellisense work 100% for a XAML {StaticResource} in Visual Studio.

Tested On

  • WPF/C#
  • Visual Studio 2015 Update 3

Step 1: Shift resources into shared project

The key is to shift all resources referenced by ResourceDictionary into a shared project:

enter image description here

Step 2: Design time intellisense

We're not quite there yet. The XAML runtime throws runtime if you include resources twice.

If we are including an .xaml file more than once in the entire project, we can include it at design time, but not at runtime:

public class DesignTimeResourceDictionary : ResourceDictionary
{
    private Uri source;

    public new Uri Source
    {
        get
        {
            if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
            {
                return null;
            }

            return this.source;
        }
        set { this.source = value; }
    }
}

Then we can add design time resources:

<!--Design time resource dictionary, so intellisense will work with with {StaticResource}.-->
<ResourceDictionary.MergedDictionaries>
    <dr:DesignTimeResourceDictionary Source="/Project.Name;component/Folder/SharedResourceA.xaml" />
    <dr:DesignTimeResourceDictionary Source="/Project.Name;component/Folder/SharedResourceB.xaml" />
</ResourceDictionary.MergedDictionaries>

If we are using ReSharper, it will offer to automatically add the namespace prefix into the header:

xmlns:dr="clr-namespace:MyNamespace;assembly=Project.Name"

Appendix A: Extra for Experts: Why the need for Step 1?

As an aside, Intellisense in XAML is the same as Intellisense in C#: it only works with sub-projects that are referenced. This is why if projects A and B want to share some code, you must put it in a class library C that is referenced by projects A and B. This is in contrast to C or C++ where #including a file in the root makes it available to all subfiles.

With XAML, you can cheat and add static resources into Main Application Project (above), and the XAML runtime will still work properly - but Intellisense won't work at design time, presumably as its based on the same engine that is used for C# intellisense.

To make Intellisense work all the time in XAML, Visual Studio Intellisense would have to scan up through every parent project (instead of just down towards referenced projects).

久隐师 2024-11-08 09:53:42

我遇到了类似的问题,这是由样式资源的构建操作引起的,该操作被设置为“资源”(听起来合适不是吗)。我在每个资源 xaml 文件的属性面板中将“构建操作”更改为“页面”(例如 Colors.xamlIcons.xamlStyles.xaml)。 xaml)。然后 Visual Studio 突然识别出了我所有的 StaticResource 引用。

I had a similar issue that was caused by the style resources' build action, which was set to "Resource" (sounds appropriate doesn't it). I changed the "Build action" to "Page", in the properties panel for each resource xaml file (e.g. Colors.xaml, Icons.xaml, Styles.xaml). Then Visual Studio suddenly recognized all my StaticResource references.

~没有更多了~
我们使用 Cookies 和其他技术来定制您的体验包括您的登录状态等。通过阅读我们的 隐私政策 了解更多相关信息。 单击 接受 或继续使用网站,即表示您同意使用 Cookies 和您的相关数据。
原文