Verwenden eines benutzerdefinierten Ausdrucks-Editors
Ein benutzerdefinierter Ausdrucks-Editor kann implementiert werden, um eine umfangreichere oder einfachere Ausdrucksbearbeitung zu ermöglichen. Es gibt mehrere Szenarios, in denen ein benutzerdefinierter Ausdrucks-Editor nützlich ist:
Zur Unterstützung von IntelliSense und anderen umfangreichen Bearbeitungsfunktionen in einem neu gehosteten Workflow-Designer. Diese Funktionalität muss bereitgestellt werden, da der standardmäßige Visual Studio-Ausdrucks-Editor nicht in neu gehosteten Anwendungen verwendet werden kann.
Zur Vereinfachung der Ausdrucksbearbeitungsumgebung z. B. für Wirtschaftsanalysten, sodass diese nicht die Arbeit mit Visual Basic oder Visual Basic-Ausdrücken lernen müssen.
Zur Implementierung eines benutzerdefinierten Ausdrucks-Editors sind drei einfache Schritte erforderlich:
Implementieren Sie die IExpressionEditorService-Schnittstelle. Über diese Schnittstelle wird die Erstellung und Löschung von Ausdrucks-Editoren verwaltet.
Implementieren Sie die IExpressionEditorInstance-Schnittstelle. Über diese Schnittstelle wird die Benutzeroberfläche zur Ausdrucksbearbeitung implementiert.
Veröffentlichen des IExpressionEditorService in der neu gehosteten Workflowanwendung.
Implementieren eines benutzerdefinierten Ausdrucks-Editors in einer Klassenbibliothek
Es folgt ein Codebeispiel für eine MyEditorService
-Klasse (Machbarkeitsstudie) zur Implementierung der IExpressionEditorService-Schnittstelle, die in einem MyExpressionEditorService-Bibliotheksprojekt enthalten ist.
using System;
using System.Collections.Generic;
using System.Activities.Presentation.View;
using System.Activities.Presentation.Hosting;
using System.Activities.Presentation.Model;
namespace MyExpressionEditorService
{
public class MyEditorService : IExpressionEditorService
{
public void CloseExpressionEditors()
{
}
public IExpressionEditorInstance CreateExpressionEditor(AssemblyContextControlItem assemblies, ImportedNamespaceContextItem importedNamespaces, List<ModelItem> variables, string text)
{
MyExpressionEditorInstance instance = new MyExpressionEditorInstance();
return instance;
}
public IExpressionEditorInstance CreateExpressionEditor(AssemblyContextControlItem assemblies, ImportedNamespaceContextItem importedNamespaces, List<ModelItem> variables, string text, System.Windows.Size initialSize)
{
MyExpressionEditorInstance instance = new MyExpressionEditorInstance();
return instance;
}
public IExpressionEditorInstance CreateExpressionEditor(AssemblyContextControlItem assemblies, ImportedNamespaceContextItem importedNamespaces, List<ModelItem> variables, string text, Type expressionType)
{
MyExpressionEditorInstance instance = new MyExpressionEditorInstance();
return instance;
}
public IExpressionEditorInstance CreateExpressionEditor(AssemblyContextControlItem assemblies, ImportedNamespaceContextItem importedNamespaces, List<ModelItem> variables, string text, Type expressionType, System.Windows.Size initialSize)
{
MyExpressionEditorInstance instance = new MyExpressionEditorInstance();
return instance;
}
public void UpdateContext(AssemblyContextControlItem assemblies, ImportedNamespaceContextItem importedNamespaces)
{
}
}
}
Im Folgenden finden Sie den Code für eine MyExpressionEditorInstance
-Klasse zur Implementierung der IExpressionEditorInstance-Schnittstelle, die in einem MyExpressionEditorService-Bibliotheksprojekt enthalten ist.
using System;
using System.Activities.Presentation.View;
using System.Windows;
using System.Reflection;
using System.Windows.Controls;
namespace MyExpressionEditorService
{
public class MyExpressionEditorInstance : IExpressionEditorInstance
{
private TextBox textBox = new TextBox();
public bool AcceptsReturn { get; set; }
public bool AcceptsTab { get; set; }
public bool HasAggregateFocus {
get
{
return true;
}
}
public System.Windows.Controls.ScrollBarVisibility HorizontalScrollBarVisibility { get; set; }
public System.Windows.Controls.Control HostControl {
get
{
return textBox;
}
}
public int MaxLines { get; set; }
public int MinLines { get; set; }
public string Text { get; set; }
public System.Windows.Controls.ScrollBarVisibility VerticalScrollBarVisibility { get; set; }
public event EventHandler Closing;
public event EventHandler GotAggregateFocus;
public event EventHandler LostAggregateFocus;
public event EventHandler TextChanged;
public bool CanCompleteWord()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanCopy()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanCut()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanDecreaseFilterLevel()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanGlobalIntellisense()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanIncreaseFilterLevel()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanParameterInfo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanPaste()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanQuickInfo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanRedo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool CanUndo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public void ClearSelection()
{
MessageBox.Show(MethodBase.GetCurrentMethod().Name);
}
public void Close()
{
MessageBox.Show(MethodBase.GetCurrentMethod().Name);
}
public bool CompleteWord()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool Copy()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool Cut()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool DecreaseFilterLevel()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public void Focus()
{
MessageBox.Show(MethodBase.GetCurrentMethod().Name);
}
public string GetCommittedText()
{
return "CommittedText";
}
public bool GlobalIntellisense()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool IncreaseFilterLevel()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool ParameterInfo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool Paste()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool QuickInfo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool Redo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
public bool Undo()
{
return (MessageBox.Show(MethodBase.GetCurrentMethod().Name, "TestEditorInstance", MessageBoxButton.YesNo) == MessageBoxResult.Yes);
}
}
}
Veröffentlichen eines benutzerdefinierten Ausdrucks-Editors in einem WPF-Projekt
Dieser Code zeigt, wie der Designer in einer WPF-Anwendung neu gehostet wird und wie der MyEditorService
-Dienst erstellt und veröffentlicht wird. Vor der Verwendung dieses Codes fügen Sie von dem Projekt aus, das die Anwendung avalon2 enthält, einen Verweis auf das MyExpressionEditorService-Bibliotheksprojekt hinzu.
using System.Windows;
using System.Windows.Controls;
using System.Activities.Presentation;
using System.Activities.Statements;
using System.Activities.Core.Presentation;
using System.Activities.Presentation.View;
using MyExpressionEditorService;
namespace WpfApplication1
{
/// <summary>
/// Interaction logic for MainWindow.xaml
/// </summary>
public partial class MainWindow : Window
{
private MyEditorService expressionEditorService;
public MainWindow()
{
InitializeComponent();
new DesignerMetadata().Register();
createDesigner();
}
public void createDesigner()
{
WorkflowDesigner designer = new WorkflowDesigner();
Sequence root = new Sequence()
{
Activities = {
new Assign(),
new WriteLine()}
};
designer.Load(root);
Grid.SetColumn(designer.View, 0);
// Create ExpressionEditorService
this.expressionEditorService = new MyEditorService();
// Publish the instance of MyEditorService.
designer.Context.Services.Publish<IExpressionEditorService>(this.expressionEditorService);
MyGrid.Children.Add(designer.View);
}
}
}
Notizen
Wenn Sie in einem benutzerdefinierten Aktivitäts-Designer ein ExpressionTextBox-Steuerelement verwenden, ist es nicht erforderlich, Ausdrucks-Editoren mithilfe der CreateExpressionEditor-Methode und der CloseExpressionEditors-Methode der IExpressionEditorService-Schnittstelle zu erstellen und zu löschen. Die ExpressionTextBox-Klasse übernimmt dies für Sie.