4

私はSilverlight4を使用していて、いくつかの一般的なスタイル(色、ブラシ)を共有しようとしています。私の考えは、それらを「Common.xaml」リソースディクショナリに入れてから、他のすべてのリソースディクショナリで使用することでした。そのようなすべてを参照する:

<Application 
  xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 
  x:Class="SampleApp.App"
>
  <Application.Resources>

    <ResourceDictionary>

      <ResourceDictionary.MergedDictionaries>
        <ResourceDictionary Source="Assets/Styles/Common.xaml"/>
        <ResourceDictionary Source="Assets/Styles/TextBoxStyle.xaml"/>
      </ResourceDictionary.MergedDictionaries>

    </ResourceDictionary>

  </Application.Resources>

</Application>

問題は、InitializeComponentで、一般的なスタイルが見つからないことを示す例外が発生することです(名前/キーを持つリソースが見つかりません...)。

使用するすべてのリソースディクショナリで「Common.xaml」を明示的に参照する必要があります。これにより、基本的に、「Common.xaml」に存在するすべての色、ブラシ、テンプレートなどの複数のインスタンスが生成されます。

リソースを共有する方法がないので、Silverlightで一度だけインスタンス化されますか?

4

4 に答える 4

4

問題は、Silverlight がリソース ディクショナリのロードを合理化して、複数のディクショナリを並行してロードできるように見えることです。その結果、あるディクショナリが別のディクショナリに依存している場合、その依存関係の準備が間に合わない場合があります。

相互依存関係を記述する組み込みの手段や、ロードされたことを示すイベントがないためResourceDictionary、私がたどり着いた唯一の解決策は、辞書のロードを自分で管理することです。

リソース ディクショナリを「手動で」ロードするために App.xaml.cs ファイルに追加できる関数を次に示します。

    private void LoadResource(Uri uri)
    {
        var info = Application.GetResourceStream(uri);
        string xaml;
        using (var reader = new StreamReader(info.Stream))
        {
            xaml = reader.ReadToEnd();
        }

        ResourceDictionary result = XamlReader.Load(xaml) as ResourceDictionary;

        if (result != null)
        {
            Resources.MergedDictionaries.Add(result);
        }
    }

Application_Startup割り当てる前に、次のRootVisualようなコードを使用します。

    LoadResource(new Uri"Assets/Styles/Common.xaml", UriKind.Relative));
    LoadResource(new Uri("Assets/Styles/TextBoxStyle.xaml", UriKind.Relative));

Sourceプロパティを使用するほど効率的ではありませんが、機能します。そのような辞書が多数あり、共有リソースを含む「一般的な」辞書がほとんどない場合は、この手法を使用して「一般的な」辞書のみをロードし、次を使用できます。

Resource.MergedDictionaries.Add(new ResourceDictionary() {Source = new Uri("Assets/Styles/TextBoxStyle.xaml", UriKind.Relative)});

相互に依存関係のない他の辞書の場合。

于 2010-11-12T09:15:13.117 に答える
1

http://www.wpftutorial.net/MergedDictionaryPerformance.htmlで提案されているソリューションを微調整して 、Silverlight と VS デザイナーで動作させることができました (Blend は試していません)。ここにブログ投稿があります ( http://softnotes.wordpress.com/2011/04/05/shared-resourcedictionary-for-silverlight/ )

public class SharedResourceDictionary : ResourceDictionary
{
    public static Dictionary<Uri, ResourceDictionary> _sharedDictionaries =
       new Dictionary<Uri, ResourceDictionary>();

    private Uri _sourceUri;
    public new Uri Source
    {
        get { return _sourceUri; }
        set
        {
            _sourceUri = value;
            if (!_sharedDictionaries.ContainsKey(value))
            {
                Application.LoadComponent(this, value);
                _sharedDictionaries.Add(value, this);
            }
            else
            {
                CopyInto(this, _sharedDictionaries[value]);
            }
        }
    }

    private static void CopyInto(ResourceDictionary copy, ResourceDictionary original)
    {
        foreach (var dictionary in original.MergedDictionaries)
        {
            var mergedCopy = new ResourceDictionary();
            CopyInto(mergedCopy, dictionary);
            copy.MergedDictionaries.Add(mergedCopy);
        }
        foreach (DictionaryEntry pair in original)
        {
            copy.Add(pair.Key, pair.Value);
        }
    }
}

XAML の使用法:

<ResourceDictionary.MergedDictionaries>
    <ui:SharedResourceDictionary Source="/my_assembly_name;component/Resources/Shared.xaml"/>
</ResourceDictionary.MergedDictionaries>
于 2011-04-05T19:15:53.247 に答える
0

このスレッドに関するもう 1 つの興味深い注意点は、スタイルが 2 つの異なる辞書にある場合、SL はそのスタイルのコピーを 1 つしか保持しないということです。最後の1つが勝ちます。つまり、同じキーを持つ 2 つの異なるスタイルがある場合、最初のスタイルは 2 番目のスタイルがロードされるときに破棄されます。

于 2013-03-09T16:55:42.993 に答える
0

読み込み中にエラーが発生した場合は、ビルド アクションが次のいずれかに設定されていることを確認してください。

//In the dll, which is in the xap, marked as Build Action: Resource or Page
LoadResource(new Uri("SilverlightApplication48;component/GlobalAssets.xaml", UriKind.Relative));

//In the xap at the same level as the dll, (not in the dll) marked as Build Action: Content.
LoadResource(new Uri("Dictionary1.xaml", UriKind.Relative));

//In a separate library, marked as Build Action: Resource or Page.
LoadResource(new Uri("StylesLibrary;component/Dictionary2.xaml", UriKind.Relative));

グレッグ

于 2013-03-07T14:06:05.093 に答える