Nota
O acesso a esta página requer autorização. Pode tentar iniciar sessão ou alterar os diretórios.
O acesso a esta página requer autorização. Pode tentar alterar os diretórios.
Essa explicação passo a passo mostra como implementar edição in-loco para um controle personalizado Windows Presentation Foundation (WPF).Você pode usar esse recurso em tempo de design na caixa Windows Presentation Foundation (WPF) Designer for Visual Studio Para definir o valor da propriedade Content em um controle de botão personalizado.Para essa explicação passo a passo, o controle é um botão simples e o adorner é um caixa de texto que permite que você alterar o conteúdo do botão.
Nesta explicação passo a passo, você executa as seguintes tarefas:
Criar um projeto de biblioteca de controle personalizado WPF .
Criar um conjunto de módulos (assembly) separado de metadados em tempo de design.
Implemente o provedor de adorno para edição In-Place.
Testar o controle em tempo de design.
Quando você terminar, você saberá como criar um provedor de adorno para um controle personalizado.
Observação: |
|---|
As caixas de diálogo e comandos de menu demonstradas podem ser diferentes daqueles descritas na Ajuda, dependendo das configurações ativas ou configurações de edição.Para alterar as configurações, escolher Importar e exportar configurações on the Ferramentas menu.Para obter mais informações, consulte Configurações do Visual Studio. |
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.
In O gerenciador de soluções, altere o nome do arquivo de código para DemoControl.cs.Se um caixa de mensagem aparecer que pergunta se você deseja executar uma renomeação para todas as referências no projeto atual, clique em Sim .
Em Gerenciador de Soluções, expanda a pasta Temas.
Clique duas vezes em Generic.xaml.
Generic.xaml é aberto no WPF Designer.
No modo de exibição XAML, substitua todas as ocorrências de "CustomControl1" com "ButtonWithDesignTime".
Abra DemoControl.cs no Editor de Código.
Substitua o código gerado automaticamente pelo código a seguir.O controle personalizado DemoControl herda de Button
using System; using System.Windows; using System.Windows.Controls; namespace CustomControlLibrary { public class DemoControl : Button { } }Defina o caminho de saída do projeto para "bin\".
Crie a solução.
Criando o Conjunto de Módulos (Assembly) de Metadados em Tempo de Design
Código em tempo de design é implantado em conjuntos de módulos (assemblies) de metadados especiais.Para obter mais informações, consulte Como: Use o Repositório de Metadados.Para essa explicação passo a passo, o adorno personalizado é suportado somente pelo Visual Studio e é implantado em um conjunto de módulos (assembly) denominado CustomControlLibrary.VisualStudio.Design.
Para criando o conjunto de módulos (assembly) de metadados em tempo de design
Adicione um novo projeto de biblioteca de classes no Visual Basic ou Visual C# denominado CustomControlLibrary.VisualStudio.Design à solução.
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 referências para os seguintes conjuntos de módulos (assemblies) WPF.
PresentationCore
PresentationFramework
WindowsBase
Adicione referências para os seguintes conjuntos de módulos (assemblies) WPF Designer:
Microsoft.Windows.Design
Microsoft.Windows.Design.Extensibility
Microsoft.Windows.Design.Interaction
Adicione uma referência ao projeto CustomControlLibrary.
Em Gerenciador de Soluções, altere o nome do arquivo de código Class1 para Metadata.cs ou Metadata.vb.
Substitua o código gerado automaticamente pelo código a seguir.Esse código cria um AttributeTable que anexa a implementação personalizada em tempo de design à classe DemoControl.
using System; using Microsoft.Windows.Design.Features; using Microsoft.Windows.Design.Metadata; namespace CustomControlLibrary.VisualStudio.Design { // Container for any general design-time metadata to initialize. // Designers look for a type in the design-time assembly that // implements IRegisterMetadata. If found, designers instantiate // this class and call its Register() method automatically. internal class Metadata : IRegisterMetadata { // Called by the designer to register any design-time metadata. public void Register() { AttributeTableBuilder builder = new AttributeTableBuilder(); // Add the adorner provider to the design-time metadata. builder.AddCustomAttributes( typeof(DemoControl), new FeatureAttribute(typeof(InplaceButtonAdorners))); MetadataStore.AddAttributeTable(builder.CreateTable()); } } }Salve a solução.
Implementando o Provedor de Adorno.
O provedor de adorno é implementado em um tipo denominado InplaceButtonAdorners.Esta adorno permite que o usuário definia a propriedade Content do controle em tempo de design.
Para implementar o provedor de adorno.
Adicione uma nova classe denominada InplaceButtonAdorners ao projeto CustomControlLibrary.Design.
No Editor de Códigos de InplaceButtonAdorners, substitua o código gerado automaticamente pelo código a seguir.Esse código implementa um PrimarySelectionAdornerProvider que fornece uma adorno baseado em um controle TextBox.
using System; using System.Collections.Generic; using System.Linq; using System.Text; using System.Windows; using System.Windows.Controls; using System.Windows.Shapes; using Microsoft.Windows.Design.Interaction; using System.Windows.Data; using System.Windows.Input; using System.ComponentModel; using Microsoft.Windows.Design.Model; namespace CustomControlLibrary.VisualStudio.Design { // The InplaceButtonAdorners class provides two adorners: // an activate glyph that, when clicked, activates in-place // editing, and an in-place edit control, which is a text box. internal class InplaceButtonAdorners : PrimarySelectionAdornerProvider { private Rectangle activateGlyph; private TextBox editGlyph; private AdornerPanel adornersPanel; public InplaceButtonAdorners() { adornersPanel = new AdornerPanel(); adornersPanel.IsContentFocusable = true; adornersPanel.Children.Add(ActivateGlyph); Adorners.Add(adornersPanel); } private UIElement ActivateGlyph { get { if (activateGlyph == null) { // The following code specifies the shape of the activate // glyph. This can also be implemented by using a XAML template. Rectangle glyph = new Rectangle(); glyph.Fill = AdornerColors.HandleFillBrush; glyph.Stroke = AdornerColors.HandleBorderBrush; glyph.RadiusX = glyph.RadiusY = 2; glyph.Width = 10; glyph.Height = 5; glyph.Cursor = Cursors.Hand; ToolTipService.SetToolTip( glyph, "Click to edit the text of the button. " + "Enter to commit, ESC to cancel."); // Position the glyph to the upper left of the DemoControl, // and slightly inside. AdornerPlacementCollection placement = new AdornerPlacementCollection(); placement.PositionRelativeToContentHeight(0, 10); placement.PositionRelativeToContentWidth(0, 5); placement.SizeRelativeToAdornerDesiredHeight(1, 0); placement.SizeRelativeToAdornerDesiredWidth(1, 0); AdornerPanel.SetPlacements(glyph, placement); // Add interaction to the glyph. A click starts in-place editing. ToolCommand command = new ToolCommand("ActivateEdit"); Task task = new Task(); task.InputBindings.Add(new InputBinding(command, new ToolGesture(ToolAction.Click))); task.ToolCommandBindings.Add(new ToolCommandBinding(command, OnActivateEdit)); AdornerProperties.SetTask(glyph, task); activateGlyph = glyph; } return activateGlyph; } } // When in-place editing is activated, a text box is placed // over the control and focus is set to its input task. // Its task commits itself when the user presses enter or clicks // outside the control. private void OnActivateEdit(object sender, ExecutedToolEventArgs args) { adornersPanel.Children.Remove(ActivateGlyph); adornersPanel.Children.Add(EditGlyph); // Once added, the databindings activate. // All the text can now be selected. EditGlyph.SelectAll(); EditGlyph.Focus(); GestureData data = GestureData.FromEventArgs(args); Task task = AdornerProperties.GetTask(EditGlyph); task.Description = "Edit text"; task.BeginFocus(data); } // The EditGlyph utility property creates a TextBox to use as // the in-place editing control. This property centers the TextBox // inside the target control and sets up data bindings between // the TextBox and the target control. private TextBox EditGlyph { get { if (editGlyph == null) { TextBox glyph = new TextBox(); glyph.BorderThickness = new Thickness(0); glyph.Margin = new Thickness(4); AdornerPlacementCollection placement = new AdornerPlacementCollection(); placement.PositionRelativeToContentWidth(0, 0); placement.PositionRelativeToContentHeight(0, 0); placement.SizeRelativeToContentHeight(1, 0); placement.SizeRelativeToContentWidth(1, 0); AdornerPanel.SetPlacements(glyph, placement); // Data bind the glyph's vertical and horizontal alignment // to the target control's alignment properties. Binding binding = new Binding(); binding.Source = glyph; binding.Path = new PropertyPath( "(0).(1)", AdornerProperties.ActualViewProperty, Button.HorizontalContentAlignmentProperty); glyph.SetBinding(TextBox.HorizontalContentAlignmentProperty, binding); binding = new Binding(); binding.Source = glyph; binding.Path = new PropertyPath( "(0).(1)", AdornerProperties.ActualViewProperty, Button.VerticalContentAlignmentProperty); glyph.SetBinding(TextBox.VerticalContentAlignmentProperty, binding); // Make the glyph's background match the control's background. binding = new Binding(); binding.Source = glyph; binding.Path = new PropertyPath( "(0).(1)", AdornerProperties.ActualViewProperty, Button.BackgroundProperty); glyph.SetBinding(TextBox.BackgroundProperty, binding); // Two-way data bind the text box's text property to content. binding = new Binding(); binding.Source = glyph; binding.Path = new PropertyPath("(0).(1)[Content].(2)", AdornerProperties.ActualModelProperty, TypeDescriptor.GetProperties( typeof(ModelItem))["Properties"], TypeDescriptor.GetProperties( typeof(ModelProperty))["ComputedValue"]); binding.Mode = BindingMode.TwoWay; binding.UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged; binding.Converter = new ContentConverter(); glyph.SetBinding(TextBox.TextProperty, binding); // Create a task that describes the UI interaction. ToolCommand commitCommand = new ToolCommand("Commit Edit"); Task task = new Task(); task.InputBindings.Add( new InputBinding( commitCommand, new KeyGesture(Key.Enter))); task.ToolCommandBindings.Add( new ToolCommandBinding(commitCommand, delegate { task.Complete(); })); task.FocusDeactivated += delegate { adornersPanel.Children.Remove(EditGlyph); adornersPanel.Children.Add(ActivateGlyph); }; AdornerProperties.SetTask(glyph, task); editGlyph = glyph; } return editGlyph; } } // The ContentConverter class ensures that only strings // are assigned to the Text property of EditGlyph. private class ContentConverter : IValueConverter { public object Convert( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { if (value is string) { return value; } return string.Empty; } public object ConvertBack( object value, Type targetType, object parameter, System.Globalization.CultureInfo culture) { return value; } } } }Crie a solução.
Testando a Implementação em Tempo de Design
Você pode usar o controle DemoControl do modo como você usaria qualquer outro controle WPF.O WPF Designer trata a criação de todos os objetos em tempo de design.
Para testar a implementação em tempo de design
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, substitua o XAML gerado automaticamente pelo seguinte XAML.Este XAML adiciona uma referência ao namespace CustomControlLibrary e adiciona o controle personalizado DemoControl.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" xmlns:ccl="clr-namespace:CustomControlLibrary;assembly=CustomControlLibrary" Title="Window1" Height="300" Width="300"> <Grid> <ccl:DemoControl></ccl:DemoControl> </Grid> </Window>Recrie a solução.
No modo Design, clique no controle DemoControl para selecioná-lo.
Um pequeno Rectangle glifo é exibido no canto superior esquerdo das DemoControl controle.
clicar no Rectangle glifo para ativar a edição in loco.
Uma caixa de texto é exibida mostrando o Content de DemoControl. Como o conteúdo é vazio no momento, você verá apenas um cursor no centralizar do botão.
Digite um novo valor para o conteúdo de texto e, em seguida, pressione a tecla ENTER.
No modo de exibição XAML, a Content propriedade é conjunto para o valor de texto que você digitou no modo de modo de exibição de Design.
conjunto projeto DemoApplication sistema autônomo o projeto de inicialização e executar a solução.
Em time de execução, o botão tem o valor de texto definido com o adorno.
Próximas etapas
Você pode adicionar mais recursos em tempo de design personalizados para os controles personalizados.
Adicione um MenuAction a seu tempo de design personalizado.Para obter mais informações, consulte Demonstra Passo a passo: Criando um MenuAction.
Criar um editor de cores personalizado, que pode ser usado na Janela de Propriedades.Para obter mais informações, consulte Demonstra Passo a passo: Implementando um editor de cor.
Crie um adorner personalizado para definir a opacidade de um controle.Para obter mais informações, consulte Demonstra Passo a passo: Criar um adorno de time de design.
Observação: