Jak połączyć zasoby importowane i lokalne w kontroli użytkownika WPF

82

Piszę kilka kontrolek użytkowników WPF, które wymagają zarówno zasobów współużytkowanych, jak i indywidualnych.

Odkryłem składnię ładowania zasobów z oddzielnego pliku zasobów:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
</UserControl.Resources>

Jednak kiedy to robię, nie mogę również dodawać zasobów lokalnie, takich jak:

<UserControl.Resources>
    <ResourceDictionary Source="ViewResources.xaml" />
    <!-- Doesn't work: -->
    <ControlTemplate x:Key="validationTemplate">
        ...
    </ControlTemplate>
    <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
        ...
    </style>
    ...
</UserControl.Resources>

Rzuciłem okiem na ResourceDictionary.MergedDictionaries, ale to pozwala mi tylko scalić więcej niż jeden zewnętrzny słownik, bez definiowania dalszych zasobów lokalnie.

Musi mi brakować czegoś trywialnego?

Należy wspomnieć: hostuję kontrolki użytkownika w projekcie WinForms, więc umieszczanie współdzielonych zasobów w App.xaml nie jest tak naprawdę opcją.

Tor Haugen
źródło

Odpowiedzi:

157

Rozgryzłem to. Rozwiązanie obejmuje MergedDictionaries, ale szczegóły muszą być odpowiednie, na przykład:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <ResourceDictionary Source="ViewResources.xaml" />
        </ResourceDictionary.MergedDictionaries>
        <!-- This works: -->
        <ControlTemplate x:Key="validationTemplate">
            ...
        </ControlTemplate>
        <style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
            ...
        </style>
        ...
    </ResourceDictionary>
</UserControl.Resources>

Oznacza to, że zasoby lokalne muszą być zagnieżdżone w tagu ResourceDictionary. Tak więc przykład tutaj jest nieprawidłowy.

Tor Haugen
źródło
5

Możesz zdefiniować zasoby lokalne w sekcji MergedDictionaries:

<UserControl.Resources>
    <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
            <!-- import resources from external files -->
            <ResourceDictionary Source="ViewResources.xaml" />

            <ResourceDictionary>
                <!-- put local resources here -->
                <Style x:key="textBoxWithError" TargetType="{x:Type TextBox}">
                    ...
                </Style>
                ...
            </ResourceDictionary>
        </ResourceDictionary.MergedDictionaries>
    </ResourceDictionary>
</UserControl.Resources>
Lu55
źródło
5

Użyj MergedDictionaries .

Mam następujący przykład stąd.

Plik1

<ResourceDictionary 
  xmlns=" http://schemas.microsoft.com/winfx/2006/xaml/presentation "
  xmlns:x=" http://schemas.microsoft.com/winfx/2006/xaml " > 
  <Style TargetType="{x:Type TextBlock}" x:Key="TextStyle">
    <Setter Property="FontFamily" Value="Lucida Sans" />
    <Setter Property="FontSize" Value="22" />
    <Setter Property="Foreground" Value="#58290A" />
  </Style>
</ResourceDictionary>

Plik 2

   <ResourceDictionary>
        <ResourceDictionary.MergedDictionaries>
          <ResourceDictionary Source="TextStyle.xaml" />
        </ResourceDictionary.MergedDictionaries>
      </ResourceDictionary> 
Preet Sangha
źródło
Dzięki, ale bez powodzenia. Jego przykład wydaje się słuszny, ale tak naprawdę nie działa. Otrzymuję komunikat „Właściwość„ Zasoby ”jest ustawiona więcej niż raz”.
Tor Haugen
Wiem o MergedDictionaries. Ale nie pozwalają mi łączyć zewnętrznego odniesienia do słownika z lokalnie zdefiniowanymi zasobami tak, jak chcę. Jak już wspomniano, na stronie, do której się odwołujesz, znajduje się przykład, ale to nie działa.
Tor Haugen
2
Dla każdego, kto otrzymuje ten błąd „ustaw więcej niż raz”: wszystkie pozostałe zasoby muszą znajdować się w pierwszym tagu <ResourceDictionary>.
Hexo