Demonstra Passo a passo: Implementando um editor de cor
O modelo de extensibilidade para o Windows Presentation Foundation (WPF) Designer for Visual Studio permite que você crie editores de valor personalizado para propriedades na Janela de Propriedades em tempo de design.Editores podem ser editores embutidos, que permitem que você edite valores diretamente na Janela de Propriedades, ou editores estendidos, que permitem que você forneça uma interface do usuário adicional para editar uma propriedade fora da Janela de Propriedades.Para demonstrar como criar um editor estendido, nesta explicação passo a passo fornece procedimentos passo a passo para criar uma cor de editor para a propriedade plano de fundo de um controle. Este editor estendida é aberta em um editor embutido na janela Propriedades.
Nesta explicação passo a passo, você executa as seguintes tarefas:
Criar um projeto de controle personalizado WPF.
Criar um controle de usuário que atuará como o editor estendido.
Criar um editor embutido que possa ser usado para editar o valor da propriedade na Janela Propriedades e para abrir o editor estendido.
Criar uma classe que herda de ExtendedPropertyValueEditor que é usada para conectar os editores à classe para qual você deseja fornecer edição personalizada.
Criar uma classe que herda de IRegisterMetadata para registrar seu novo editor estendido.
Testar o editor estendido em tempo de design.
Pré-requisitos
Para completar este passo a passo, são necessários os seguintes componentes:
- Visual Studio 2008.
Criando o Controle Personalizado
A primeira etapa é criar o projeto para o controle personalizado.O controle é um botão simples com pequena quantidade de código em tempo de design, que usa o método GetIsInDesignMode para implementar um comportamento de tempo de design.
Para criar o controle personalizado
Crie um novo projeto da biblioteca de controle personalizado WPF no Visual C# denominado CustomControlLibrary .
O código de CustomControl1 abre no Editor de Códigos.
Adicione uma referência ao seguinte conjunto de módulos (assembly) WPF Designer.
- Microsoft.Windows.Design
No Editor de Códigos de CustomControl1, substitua o código no namespace CustomControlLibrary com o seguinte código:
public class CustomControl1 : Button { public CustomControl1() { if (System.ComponentModel.DesignerProperties.GetIsInDesignMode(this)) { Background = Brushes.Red; } } }
Defina o caminho de saída do projeto para "bin\".
Crie a solução.
Criando o Controle de Usuário para o Editor Estendido
O controle que você criou no procedimento anterior é o controle ao qual você irá anexar seu editor de cores personalizado.Nesse procedimento, você criará outro controle de usuário que atuará como o editor estendido.
Para criar um controle de usuário que atuará como o editor estendido
Adicione um novo projeto da biblioteca de controle personalizado WPF no Visual C# denominado CustomControlLibrary.Design à solução.
O código de CustomControl1 abre no Editor de Códigos.
Em Gerenciador de Soluções, exclua o arquivo CustomControl1 do projeto CustomControlLibrary.Design.
Adicione uma referência ao seguinte conjunto de módulos (assembly) WPF Designer.
- Microsoft.Windows.Design
Adicione uma referência ao projeto CustomControlLibrary.
conjunto caminho de saída do projeto para "..\CustomControlLibrary\bin\ ".Isso mantém o conjunto de módulos (assembly) do controle e o conjunto de módulos (assembly) de metadados na mesma pasta, o que permite a descoberta de metadados para os designers.
Adicione uma nova classe denominada ColorsList ao projeto CustomControlLibrary.Design.
No Editor de Códigos de ColorsList, substitua o código gerado automaticamente pelo código a seguir.
using System; using System.Linq; using System.Collections.Generic; using System.Text; using System.Windows.Media; using System.Reflection; using System.Collections.ObjectModel; namespace ColorsListNamespace { public class ColorsList : ObservableCollection<Color> { public ColorsList() { Type type = typeof(Colors); foreach (PropertyInfo propertyInfo in type.GetProperties(BindingFlags.Public | BindingFlags.Static)) { if (propertyInfo.PropertyType == typeof(Color)) { Add((Color)propertyInfo.GetValue(null, null)); } } } } }
Adicione um novo controle de usuário (WPF) denominado ColorsListControl ao projeto CustomControlLibrary.Design.
O código para ColorsListControl.xaml abre no designer.
No modo de exibição XAML para ColorsListControl.xaml, substitua o XAML gerado automaticamente pelo seguinte XAML.
<UserControl x:Class="ColorsListNamespace.ColorsListControl" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" xmlns:Local="clr-namespace:ColorsListNamespace" xmlns:PropertyEditing="clr-namespace:Microsoft.Windows.Design.PropertyEditing;assembly=Microsoft.Windows.Design" Height="184" Width="260" Background="White"> <UserControl.Resources> <Local:ColorsList x:Key="colors"/> <Style TargetType="{x:Type Button}"> <EventSetter Event="Click" Handler="ItemsControl_Click"/> </Style> </UserControl.Resources> <ItemsControl ItemsSource="{Binding Source={StaticResource colors}}" HorizontalContentAlignment="Stretch" VerticalContentAlignment="Stretch" HorizontalAlignment="Stretch" VerticalAlignment="Stretch"> <ItemsControl.Template> <ControlTemplate TargetType="ItemsControl"> <Border CornerRadius="5" > <WrapPanel Orientation="Horizontal" VerticalAlignment="Center" HorizontalAlignment="Center"> <ScrollViewer> <ItemsPresenter/> </ScrollViewer> </WrapPanel> </Border> </ControlTemplate> </ItemsControl.Template> <ItemsControl.ItemsPanel> <ItemsPanelTemplate> <WrapPanel/> </ItemsPanelTemplate> </ItemsControl.ItemsPanel> <ItemsControl.ItemTemplate> <DataTemplate> <Button Tag="{Binding}" Command="{x:Static PropertyEditing:PropertyValueEditorCommands.ShowInlineEditor}"> <Button.Template> <ControlTemplate> <Border Width="30" Height="30" BorderBrush="Black" BorderThickness="1" CornerRadius="5"> <Rectangle Width="22" Height="22" ToolTip="{Binding}"> <Rectangle.Fill> <SolidColorBrush Color="{Binding}"/> </Rectangle.Fill> </Rectangle> </Border> </ControlTemplate> </Button.Template> </Button> </DataTemplate> </ItemsControl.ItemTemplate> </ItemsControl> </UserControl>
Em Gerenciador de Soluções, expanda ColorsListControl.xaml e abra ColorsListControl.xaml.cs.
No Editor de Códigos de ColorsListControl, substitua o código gerado automaticamente pelo código a seguir.
using System; using System.Linq; using System.Collections; using System.Collections.Generic; using System.Diagnostics; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Data; using System.Windows.Documents; using System.Windows.Input; using System.Windows.Media; using System.Windows.Media.Imaging; using System.Windows.Navigation; using System.Windows.Shapes; namespace ColorsListNamespace { public partial class ColorsListControl : System.Windows.Controls.UserControl { public static readonly RoutedEvent ClosePopupEvent = EventManager.RegisterRoutedEvent("ClosePopupEvent", RoutingStrategy.Direct, typeof(RoutedEventHandler), typeof(ColorsListControl)); public ColorsListControl() { InitializeComponent(); } public static readonly DependencyProperty SelectedColorProperty = DependencyProperty.Register("SelectedColor", typeof(Color), typeof(ColorsListControl), new FrameworkPropertyMetadata(null)); public Color SelectedColor { get { return (Color)base.GetValue(SelectedColorProperty); } set { base.SetValue(SelectedColorProperty, value); } } public static readonly DependencyProperty SelectedBrushProperty = DependencyProperty.Register("SelectedBrush", typeof(SolidColorBrush), typeof(ColorsListControl), new FrameworkPropertyMetadata(null)); public SolidColorBrush SelectedBrush { get { return (SolidColorBrush)base.GetValue(SelectedBrushProperty); } set { base.SetValue(SelectedBrushProperty, value); } } public event RoutedEventHandler ClosePopup { add { AddHandler(ClosePopupEvent, value); } remove { RemoveHandler(ClosePopupEvent, value); } } protected void RaiseClosePopupEvent() { RoutedEventArgs newEventArgs = new RoutedEventArgs(ColorsListControl.ClosePopupEvent); RaiseEvent(newEventArgs); } private void ItemsControl_Click(object sender, RoutedEventArgs e) { SelectedColor = (Color)((Button)sender).Tag; SelectedBrush = new SolidColorBrush(SelectedColor); RaiseClosePopupEvent(); } } }
Crie a solução.
Recarregue ColorsListControl.xaml no designer e você deverá ver a interface do usuário do editor estendido aparecer no modo Design.
Criando os Modelos para o Editor de Cores
O editor embutido para seu editor de cores é menos complexo do que o editor estendido e pode ser criado com um modelo de dados XAML.Você também criará um modelo de dados para o editor estendido que especifica usar o controle de usuário que você criou no procedimento anterior.
Para criar o modelo para o editor de cores
Adicione uma nova classe denominada EditorResources ao projeto CustomControlLibrary.Design.
No Editor de Códigos de EditorResources, substitua o código gerado automaticamente pelo código a seguir.
namespace ExtendedEditorNamespace { using System; using System.Collections.Generic; using System.Text; using System.Windows; public partial class EditorResources : ResourceDictionary { public EditorResources() : base() { InitializeComponent(); } } }
No menu Project, clique em Add Resource Dictionary.
Nomeie o arquivo EditorResources.xaml e clique em Adicionar.
O código para EditorResources.xaml abre no designer.
No modo de exibição XAML para EditorResources.xaml, substitua o XAML gerado automaticamente pelo seguinte XAML.
<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" xmlns:Local="clr-namespace:ColorsListNamespace" xmlns:Media="clr-namespace:System.Windows.Media;assembly=PresentationCore" xmlns:sys="clr-namespace:System;assembly=mscorlib" x:Class="ExtendedEditorNamespace.EditorResources"> <DataTemplate x:Key="BrushExtendedEditorTemplate"> <Local:ColorsListControl SelectedBrush="{Binding Value, Mode=TwoWay}"/> </DataTemplate> <DataTemplate x:Key="BrushInlineEditorTemplate"> <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>
Crie a solução.
Encapsulando os Modelos e Registrando os Editores
O trabalho pesado está concluído.Agora que você criou os modelos de editores estendido e embutido para seu editor de cores, você pode criar uma classe que encapsula-os e registra-os com seu controle personalizado.
Para encapsular e registrar os editores
Adicione uma nova classe denominada BrushExtendedEditor ao projeto CustomControlLibrary.Design.
No Editor de Códigos de BrushExtendedEditor, substitua o código gerado automaticamente pelo código a seguir.
namespace ExtendedEditorNamespace { using System; using System.Collections.Generic; using System.Text; using Microsoft.Windows.Design.PropertyEditing; using System.Windows; using ExtendedEditorNamespace; public class BrushExtendedEditor : ExtendedPropertyValueEditor { private EditorResources res = new EditorResources(); public BrushExtendedEditor() { this.ExtendedEditorTemplate = res["BrushExtendedEditorTemplate"] as DataTemplate; this.InlineEditorTemplate = res["BrushInlineEditorTemplate"] as DataTemplate; } } }
Adicione uma nova classe denominada Metadata ao projeto CustomControlLibrary.Design.
No Editor de Códigos de Metadata, substitua o código gerado automaticamente pelo código a seguir.
namespace ExtendedEditorNamespace { using System; using System.Collections.Generic; using System.Text; using Microsoft.Windows.Design.Metadata; using System.ComponentModel; using Microsoft.Windows.Design.PropertyEditing; using System.Windows.Media; using System.Windows.Controls; using System.Windows; using CustomControlLibrary; // Container for any general design-time metadata that we want to initialize. // Designers will look for a type in the design-time assembly that implements IRegisterMetadata. // If found, they will instantiate it and call its Register() method automatically. internal class Metadata : IRegisterMetadata { // Called by Cider to register any design-time metadata public void Register() { AttributeTableBuilder builder = new AttributeTableBuilder(); builder.AddCustomAttributes (typeof(CustomControl1), Control.BackgroundProperty, PropertyValueEditor.CreateEditorAttribute( typeof(BrushExtendedEditor))); MetadataStore.AddAttributeTable(builder.CreateTable()); } } }
Crie a solução.
Testando o Editor de Cores
Você acabou de concluir a criação de seu editor de cores.Tudo que resta agora é testá-lo.Para testar o seu editor, você adicionará um projeto de aplicativo WPF à sua solução e adicionará seu controle personalizado.Em seguida, você alterará o plano de fundo na Janela de Propriedades e verá seu novo editor em ação.
Para testar o editor de cores
Adicione um novo projeto de aplicativo WPF no Visual C# denominado DemoApplication à solução.
Window1.xaml é aberto no WPF Designer.
Adicione uma referência ao projeto CustomControlLibrary.
No modo de exibição XAML para Window1.xaml, substitua o XAML gerado automaticamente pelo seguinte XAML.Este XAML adiciona uma referência ao namespace CustomControlLibrary e adiciona o controle personalizado CustomControl1.O botão aparece no modo Design com um plano de fundo vermelho, indicando que o controle está no modo de design.Se o botão não for exibido, talvez você precise clicar na Barra de Informações na parte superior do designer para recarregar o modo de exibição.
<Window x:Class="DemoApplication.Window1" xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" Title="Window1" Height="300" Width="300" xmlns:my="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary"> <Grid> <my:CustomControl1 Margin="30,30,30,30" Name="customControl11">Button</my:CustomControl1> </Grid> </Window>
No modo de exibição do Designer, selecione o controle.
Na janela Propriedades, clique no botão suspenso próximo à propriedade de Plano de Fundo.Um editor de cores visual é exibido no lugar da lista de cores padrão.
Selecione uma cor do editor.O plano de fundo de seu controle personalizado muda para aquela cor.
Consulte também
Tarefas
Demonstra Passo a passo: Implementando um editor de valores em linha
Como: Criar um editor de valores