Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Avoiding Visual Studio designer errors when WPF resource is defined in separate project

How can I avoid Visual Studio designer errors when a WPF resource is defined in separate project?

I have three projects in a composite WPF application: the main application, an "infrastructure" library, and a "module" library. The main application references the other projects via their output DLLs (the projects are not located in a single solution together).

I am defining a skin (some brushes and styles in a ResourceDictionary) in the "infrastructure" library. I would like the main application to select a skin and make it available to the entire application (via MergedDictionaries in App.xaml).

In my module I want to use the resources defined in the skin that the main application loads. If I reference the resource as if it were locally available like this:

Background={StaticResource MainBackgroundBrush}

almost everything works as desired. The exception is that Visual Studio's designer gets confused and tells me that "StaticResource reference 'MainBackgroundBrush' was not found". This effectively prevents me from using the designer.

What can I do to define a "skin" ResourceDictionary in a project, reference that skin in the main application, and then use its resources in a module project?

like image 728
sourcenouveau Avatar asked Jul 06 '09 19:07

sourcenouveau


People also ask

Can we design web based app in WPF without XAML as well?

But WPF without XAML is possible. You don't even need Visual Studio installed for this, just the . NET CLI and the Developer Command Prompt. Drop these two files in a folder and run msbuild and then you can run the file in the Bin directory.

How do I disable XAML designer?

In Visual Studio 2015/2017/2019/2022: In the Tools -> Otions menu, open the XAML Designer node, then uncheck "Enable XAML Designer"

What are different types of resources in WPF and their scope?

WPF supports different types of resources. These resources are primarily two types of resources: XAML resources and resource data files. Examples of XAML resources include brushes and styles. Resource data files are non-executable data files that an application needs.

What is static resource in WPF?

Static Resource - Static resources are the resources which you cannot manipulate at runtime. The static resources are evaluated only once by the element which refers them during the loading of XAML.


3 Answers

You could create your own ResourceDictionary class, inheriting from ResourceDictionary. Then you can arrange that at design-time this custom ResourceDictionary loads some explicitly defined styles (i.e. those loaded from the app at runtime), whereas at runtime it does nothing at all. The IsInDesignMode-Property could be evaluated for this.

Say you have such a class, called 'DesignTimeResourceDictionary', then you just use s.th. like

 <UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <Util:DesignTimeResourceDictionary Source="SomeUriToYourResources"/>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
 </UserControl.Resources>

to load your resources at design-time and make the designer work. At Runtime you can then make your DesignTimeResourceDictionary skip the loading of resources and achieve the desired behavior.

If you need, you could really create a copy of the real resources for this, or you can just create a dummy dictionary containing all the keys you need to keep the designer working.

like image 145
Simon D. Avatar answered Oct 11 '22 11:10

Simon D.


One possible solution is to use DynamicResource rather than StaticResource. The Visual Studio 2008 designer simply displays the controls without any styling, like VS2010 beta 1 does when it cannot resolve a StaticResource.

Using DynamicResource is appropriate in situations where a particular style may change at runtime, like when skinning.

I found some related questions supporting this:

  • Assembly-wide / root-level styles in WPF class library
  • What’s the difference between StaticResource and DynamicResource in WPF?
  • WPF - Dynamic vs Static Resources

I also found someone who states that DynamicResource should be used whenever a resource is not local:

  • Static vs Dynamic Resources
like image 35
sourcenouveau Avatar answered Oct 11 '22 09:10

sourcenouveau


I just want to extend Simon D. answer. What he is proposing is the solution that i am using right now. I just wanted to share complete source code. It is from this Trick To Use A ResourceDictionary Only When In Design Mode source.

public class DesignTimeResourceDictionary : ResourceDictionary
{
    /// <summary>
    /// Local field storing info about designtime source.
    /// </summary>
    private string designTimeSource;

    /// <summary>
    /// Gets or sets the design time source.
    /// </summary>
    /// <value>
    /// The design time source.
    /// </value>
    public string DesignTimeSource
    {
        get
        {
            return this.designTimeSource;
        }

        set
        {
            this.designTimeSource = value;
            if ((bool)DesignerProperties.IsInDesignModeProperty.GetMetadata(typeof(DependencyObject)).DefaultValue)
            {
                base.Source = new Uri(designTimeSource);
            }
        }
    }

    /// <summary>
    /// Gets or sets the uniform resource identifier (URI) to load resources from.
    /// </summary>
    /// <returns>The source location of an external resource dictionary. </returns>
    public new Uri Source
    {
        get
        {
            throw new Exception("Use DesignTimeSource instead Source!");
        }

        set
        {
            throw new Exception("Use DesignTimeSource instead Source!");
        }
    }
}

<Window x:Class="WpfApplication1.MainWindow"
    xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation Jump "
    xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml Jump "
    Title="MainWindow" Height="350" Width="525"
    xmlns:local="clr-namespace:WpfApplication1">

  <Window.Resources>
    <local:DesignTimeResourceDictionary DesignTimeSource="pack://application:,,,/BlueColors.xaml"/>
  </Window.Resources>

    <Grid>
      <Button Background="{DynamicResource defaultBackground}"
      HorizontalAlignment="Center" VerticalAlignment="Center">click me</Button>
    </Grid>
</Window>
like image 30
Tomas Kosar Avatar answered Oct 11 '22 09:10

Tomas Kosar