Éviter les erreurs de concepteur Visual Studio lorsque la ressource WPF est défini dans le projet séparé

StackOverflow https://stackoverflow.com/questions/1088762

Question

Comment puis-je éviter les erreurs de concepteur Visual Studio lorsqu'une ressource WPF est défini dans le projet séparé?

I ai trois projets dans une application composite WPF: L'application principale, une bibliothèque "infrastructure", et une bibliothèque de "module". La principale application fait référence aux autres projets via leurs DLL de sortie (les projets ne sont pas situés dans une seule solution ensemble).

Je suis en train de définir une peau (quelques pinceaux et styles dans un ResourceDictionary) dans la bibliothèque « infrastructure ». Je voudrais l'application principale pour sélectionner une peau et la rendre disponible à l'ensemble de l'application (via MergedDictionaries en App.xaml).

Dans mon module, je veux utiliser les ressources définies dans la peau que les charges d'application des principales. Si je fais référence à la ressource comme si elle était disponible localement comme ceci:

Background={StaticResource MainBackgroundBrush}

presque tout fonctionne comme vous le souhaitez. L'exception est que le concepteur de Visual Studio se confond et me dit que « la référence StaticResource « MainBackgroundBrush » n'a pas été trouvé ». Cela me empêche d'utiliser efficacement le concepteur.

Que puis-je faire pour définir une ResourceDictionary « peau » dans un projet, une référence que la peau dans l'application principale, puis utiliser ses ressources dans un projet de module?

Était-ce utile?

La solution 2

Une solution possible est d'utiliser DynamicResource plutôt que StaticResource. Visual Studio 2008 affiche concepteur simplement les commandes sans style, comme VS2010 beta 1 quand il ne peut pas résoudre une StaticResource.

Utilisation DynamicResource est appropriée dans les situations où un style particulier peut changer lors de l'exécution, comme quand écorcher.

J'ai trouvé quelques questions connexes soutenant ceci:

J'ai aussi trouvé quelqu'un qui déclare que DynamicResource doit être utilisé chaque fois qu'une ressource est pas local:

Autres conseils

Vous pouvez créer votre propre classe ResourceDictionary, héritant de ResourceDictionary. Ensuite, vous pouvez organiser que lors de la conception du temps cette charge personnalisée ResourceDictionary certains styles explicitement définis (par exemple ceux chargés de l'application lors de l'exécution), alors que lors de l'exécution, il ne fait rien du tout. Le IsInDesignMode-propriété pourrait être évaluée pour cela.

Disons que vous avez une telle classe, appelée « DesignTimeResourceDictionary », vous utilisez juste s.th. comme

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

pour charger vos ressources à temps de conception et de faire le travail de designer. Lors de l'exécution, vous pouvez alors faire votre DesignTimeResourceDictionary sauter le chargement des ressources et obtenir le comportement souhaité.

Si vous avez besoin, vous pourriez vraiment créer une copie des ressources réelles pour cela, ou vous pouvez simplement créer un dictionnaire contenant factice toutes les clés que vous devez garder le concepteur de travail.

Je veux juste étendre Simon D. réponse. Ce qu'il propose est la solution que j'utilise en ce moment. Je voulais juste partager le code source complet. Il est de ce Trick Pour utiliser un ResourceDictionary uniquement en mode source de conception.

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>
scroll top