Создание WPF библиотеки окон, контролов, ресурсов и стилей.
Часто возникает ситуация когда несколько WPF приложений используют одни и те же окна, контролы, стили и ресурсы. Самым лучшим решением является - вынести все совместно используемые компоненты в отдельную DLL сборку. Но на практике оказывается все не так просто. Эти осложнения обусловлены тем, что Visual Studio 2008 не позволяет добавлять, некоторые элементы WPF, такие например как ResourceDictionary и Window, в ClassLibrary проект. Далее я расскажу, как создавать WPF библиотеки на основе ClassLibrary проекта.
Создадим Solution и добавим туда 3 проекта:
- WpfApplication1 - WPF Application
- WpfApplication2 - WPF Application
- WpfLibrary - Class Library
Добавим Resource Dictionary в каждый из созданных проектов. Назовем их везде одинаково - ResourceDictionary.
Примечание: Visual Studio 2008 не позволяет добавлять некоторые элементы WPF приложения в Class Library проект. Поэтому сначала следует создать необходимый элемент в проекте WPF Application, а потом перенести его в проект Class Library. Причем, после переноса файлов необходимо изменить значение атрибута Build Action на Page.
Добавим ресурсы и стили в ResourceDictionary.
WpfApplication1:
ResourceDictionary.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<s:String x:Key="WpfApplication1String">Строка из WpfApplication1</s:String>
<Style x:Key="WpfApplication1Style"
TargetType="TextBlock">
<Setter Property="Background" Value="Blue" />
</Style>
</ResourceDictionary>
WpfApplication2:
ResourceDictionary.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<s:String x:Key="WpfApplication2String">Строка из WpfApplication2</s:String>
<Style x:Key="WpfApplication2Style"
TargetType="TextBlock">
<Setter Property="Background" Value="Green" />
</Style>
</ResourceDictionary>
WpfLibrary:
ResourceDictionary.xaml:
<ResourceDictionary xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:s="clr-namespace:System;assembly=mscorlib">
<s:String x:Key="WpfLibraryString">Строка из WpfLibrary</s:String>
<Style x:Key="WpfLibraryStyle"
TargetType="TextBlock">
<Setter Property="Background" Value="Red" />
</Style>
</ResourceDictionary>
Сделаем созданные Resource Dictionary, видимыми во всем приложении для WpfApplication1 и WpfApplication2. Для этого включим созданные Resource Dictionary в App.xaml.
WpfApplication1:
App.xaml:
<Application x:Class="WpfApplication1.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
<ResourceDictionary Source="pack://application:,,,/WpfLibrary;component/ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
WpfApplication2:
App.xaml:
<Application x:Class="WpfApplication2.App"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
StartupUri="Window1.xaml">
<Application.Resources>
<ResourceDictionary>
<ResourceDictionary.MergedDictionaries>
<ResourceDictionary Source="ResourceDictionary.xaml"/>
<ResourceDictionary Source="pack://application:,,,/WpfLibrary;component/ResourceDictionary.xaml"/>
</ResourceDictionary.MergedDictionaries>
</ResourceDictionary>
</Application.Resources>
</Application>
Создадим User Control (WPF) в WpfLibrary и назовем его UserControl1. И используем в этом контроле стили и ресурсы, определенные в ResourceDictionary в проекте WpfLibrary.
WpfLibrary:
UserControl1.xaml:
<UserControl x:Class="WpfLibrary.UserControl1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Height="100" Width="200">
<TextBlock Style="{StaticResource WpfLibraryStyle}"
Text="{StaticResource WpfLibraryString}"/>
</UserControl>
Далее, создадим Window в WpfLibrary с названием CustomWindow.
WpfLibrary:
CustomWindow.xaml:
<Window x:Class="WpfLibrary.CustomWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfLibrary="clr-namespace:WpfLibrary"
Title="Custom Window"
SizeToContent="WidthAndHeight">
<WpfLibrary:UserControl1/>
</Window>
Теперь изменим главные окна Window1 приложений WpfApplication1 и WpfApplication2 так, чтобы они использовали окно, контрол, стиль и ресурс из WpfLibrary, наряду со стилями и ресурсами, определенными в самом WPF приложении.
WpfApplication1:
Window1.xaml:
<Window x:Class="WpfApplication1.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfLibrary="clr-namespace:WpfLibrary;assembly=WpfLibrary"
Title="WpfApplication1"
Height="320" Width="300">
<StackPanel Orientation="Vertical">
<TextBlock Style="{StaticResource WpfApplication1Style}"
Text="{StaticResource WpfApplication1String}"
HorizontalAlignment="Center"
Height="80" Width="200"/>
<TextBlock Style="{StaticResource WpfLibraryStyle}"
Text="{StaticResource WpfLibraryString}"
HorizontalAlignment="Center"
Height="80" Width="200"/>
<WpfLibrary:UserControl1 HorizontalAlignment="Center"
Height="80" Width="200" />
<Button Content="Show Window"
Click="Button_Click"
HorizontalAlignment="Center"
Height="30" Width="100"/>
</StackPanel>
</Window>
Window1.xaml.cs:
using System.Windows;
using WpfLibrary;
namespace WpfApplication1
{
public partial class Window1
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var wnd = new CustomWindow { Owner = this };
wnd.ShowDialog();
}
}
}
WpfApplication2:
Window1.xaml:
<Window x:Class="WpfApplication2.Window1"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:WpfLibrary="clr-namespace:WpfLibrary;assembly=WpfLibrary"
Title="WpfApplication2"
Height="320" Width="300">
<StackPanel Orientation="Vertical">
<TextBlock Style="{StaticResource WpfApplication2Style}"
Text="{StaticResource WpfApplication2String}"
HorizontalAlignment="Center"
Height="80" Width="200"/>
<TextBlock Style="{StaticResource WpfLibraryStyle}"
Text="{StaticResource WpfLibraryString}"
HorizontalAlignment="Center"
Height="80" Width="200"/>
<WpfLibrary:UserControl1 HorizontalAlignment="Center"
Height="80" Width="200" />
<Button Content="Show Window"
Click="Button_Click"
HorizontalAlignment="Center"
Height="30" Width="100"/>
</StackPanel>
</Window>
Window1.xaml.cs:
using System.Windows;
using WpfLibrary;
namespace WpfApplication2
{
public partial class Window1
{
public Window1()
{
InitializeComponent();
}
private void Button_Click(object sender, RoutedEventArgs e)
{
var wnd = new CustomWindow { Owner = this };
wnd.ShowDialog();
}
}
}
Запустим приложения
Видим, что контрол, окно, ресурс и стиль из WpfLibrary используются в двух разных приложениях WPF.
Ссылка на скачивание Solution: WPFLibrary.zip
Spaniard
31.07.2009 14:08
Скачаю и проанализирую. Спасибо, это интересно, Андрей-доно =)