Практическое руководство. Создание редактора значений свойств диалогового окна
В следующем примере кода показано, как реализовать пользовательский редактор значений свойств диалогового окна для Конструктор WPF для Visual Studio. Полное решение см. в примере "Dialog Property Value Editor" в разделе WPF Designer Extensibility Samples веб-сайта корпорации Майкрософт.
Пример
В данном разделе показано, как создать редактор значений свойств диалогового окна, отображающий диалоговое окно с открытым файлом при щелчке пользовательского свойства FileName в окне "Свойства".
using System;
using System.ComponentModel;
using System.Windows.Controls;
using System.Windows;
namespace CustomControlLibrary
{
public partial class DemoControl : UserControl
{
public DemoControl()
{
InitializeComponent();
}
public static readonly DependencyProperty FileNameProperty = DependencyProperty.Register(
"FileName",
typeof(string),
typeof(DemoControl),
new PropertyMetadata("File name not set."));
public string FileName
{
get
{
return (string)this.GetValue(FileNameProperty);
}
set
{
this.SetValue(FileNameProperty, value);
}
}
}
}
<ResourceDictionary xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design.Interaction"
xmlns:Local="clr-namespace:CustomControlLibrary.Design"
x:Class="CustomControlLibrary.Design.EditorResources">
<DataTemplate x:Key="FileBrowserInlineEditorTemplate">
<Grid>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="1*"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<TextBox Grid.Column="0" Text="{Binding StringValue}"/>
<PropertyEditing:EditModeSwitchButton Grid.Column="1"/>
</Grid>
</DataTemplate>
</ResourceDictionary>
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
namespace CustomControlLibrary.Design
{
using System.Windows;
public partial class EditorResources : ResourceDictionary
{
public EditorResources()
: base()
{
InitializeComponent();
}
}
}
using System;
using System.ComponentModel;
using System.Windows;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.PropertyEditing;
using Microsoft.Win32;
namespace CustomControlLibrary.Design
{
public class FileBrowserDialogPropertyValueEditor : DialogPropertyValueEditor
{
private EditorResources res = new EditorResources();
public FileBrowserDialogPropertyValueEditor()
{
this.InlineEditorTemplate = res["FileBrowserInlineEditorTemplate"] as DataTemplate;
}
public override void ShowDialog(
PropertyValue propertyValue,
IInputElement commandSource)
{
OpenFileDialog ofd = new OpenFileDialog();
ofd.Multiselect = false;
if (ofd.ShowDialog() == true)
{
propertyValue.StringValue = ofd.FileName;
}
}
}
}
using System;
using System.ComponentModel;
using System.Windows;
using Microsoft.Windows.Design.Metadata;
using Microsoft.Windows.Design.PropertyEditing;
// The ProvideMetadata assembly-level attribute indicates to designers
// that this assembly contains a class that provides an attribute table.
[assembly: ProvideMetadata(typeof(CustomControlLibrary.Design.Metadata))]
namespace CustomControlLibrary.Design
{
// Container for any general design-time metadata to initialize.
// Designers look for a type in the design-time assembly that
// implements IProvideAttributeTable. If found, designers instantiate
// this class and access its AttributeTable property automatically.
internal class Metadata : IProvideAttributeTable
{
// Accessed by the designer to register any design-time metadata.
public AttributeTable AttributeTable
{
get
{
AttributeTableBuilder builder = new AttributeTableBuilder();
builder.AddCustomAttributes
(typeof(CustomControlLibrary.DemoControl),
"FileName",
PropertyValueEditor.CreateEditorAttribute(
typeof(FileBrowserDialogPropertyValueEditor)));
return builder.CreateTable();
}
}
}
}
<Window x:Class="WpfApplication1.MainWindow"
xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
xmlns:ccl="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"
Title="MainWindow" Height="300" Width="300">
<Grid>
<ccl:DemoControl FileName="" />
</Grid>
</Window>
Компиляция кода
Скомпилируйте код из предыдущего примера в трех отдельных сборках.
Компиляция пользовательского элемента управления
В Visual Studio создайте новый проект библиотеки пользовательских элементов управления WPF на языке C# с именем CustomControlLibrary.
Измените все вхождения "UserControl1" на "DemoControl".
Замените существующий код в классе DemoControl на код, представленный выше.
Выполните построение решения.
Компиляция пользовательского редактора значений свойств диалогового окна
В Visual Studio добавьте к решению новый проект библиотеки пользовательских элементов управления WPF с именем CustomControlLibrary.Design.
Задайте выходной путь проекта как ".. \CustomControlLibrary\bin\Debug\".
Удалите из проекта файлы UserControl1.xaml и UserControl1.xaml.cs.
Добавьте ссылки на следующие сборки:
Microsoft.Windows.Design.Extensibility
Microsoft.Windows.Design.Interaction
Добавьте ссылку на проект CustomControlLibrary.
Добавьте к проекту словарь ресурсов с именем EditorResources.
Замените существующий код XAML в файле EditorResources.xaml на приведенный выше код XAML.
Добавьте к проекту новый класс с именем EditorResources.
Замените существующий код класса "EditorResources" на код, представленный выше.
Добавьте к проекту новый класс с именем FileBrowserDialogPropertyValueEditor.
Замените существующий код в классе FileBrowserDialogPropertyValueEditor на код, представленный выше.
Добавьте в проект новый класс с именем Metadata.
Замените существующий код в классе Metadata на код, представленный выше.
Выполните построение решения.
Компиляция тестового приложения
В Visual Studio добавьте к решению новый проект приложения WPF.
Добавьте ссылку на сборку или проект CustomControlLibrary.
В представлении XAML для файла MainWindow.xaml замените существующий код на код, представленный выше.
В файле MainWindow.xaml.cs установите метки комментария для вызова InitializeComponent.
Перестройте решение.
В представлении конструктора выберите элемент управления DemoControl. При необходимости щелкните панель информации в верхней части конструктора, чтобы перезагрузить представление.
В окне "Свойства" нажмите кнопку рядом со свойством FileName.
Откроется диалоговое окно Открыть.
Выберите файл и нажмите кнопку Открыть.
Имя файла отображается в свойстве FileName окна "Свойства" и свойство FileName назначается в представлении XAML.
См. также
Ссылки
Другие ресурсы
Дополнительные понятия расширяемости