| name | xaf-winforms-ui |
| description | XAF WinForms UI platform - WinApplication setup, Ribbon vs Standard toolbar, WinForms-specific editors (XtraGrid, DevExpress controls), Detail View layout customization via Layout Manager, custom WinForms controls embedded in XAF views, background workers for thread-safe UI updates, splash screen customization, WinForms navigation (NavigationFrame), printing/preview in WinForms, ClickOnce/MSI deployment. Use when building or customizing XAF WinForms applications. |
XAF: WinForms UI Platform
Application Setup
[STAThread]
static void Main() {
Application.EnableVisualStyles();
Application.SetCompatibleTextRenderingDefault(false);
var winApplication = new MyWinApplication();
winApplication.Setup();
winApplication.Start();
}
public class MyWinApplication : WinApplication {
public MyWinApplication() {
DatabaseUpdateMode = DatabaseUpdateMode.UpdateDatabaseAlways;
CheckCompatibilityType = CheckCompatibilityType.DatabaseSchema;
}
protected override void OnSetupStarted() {
base.OnSetupStarted();
ConnectionString = ConfigurationManager.ConnectionStrings["Default"].ConnectionString;
}
}
Ribbon vs Standard Toolbar
Switch to Ribbon
UseOldTemplates = false;
Customize Ribbon Categories
Custom Ribbon Button from Controller
public class CustomRibbonController : WindowController {
private SimpleAction customAction;
public CustomRibbonController() {
customAction = new SimpleAction(this, "CustomAction", "CustomCategory") {
Caption = "Custom",
ImageName = "Action_New",
PaintStyle = ActionItemPaintStyle.CaptionAndImage
};
customAction.Execute += CustomAction_Execute;
}
}
WinForms-Specific Editors
| Data Type | WinForms Editor | DevExpress Control |
|---|
| string | StringPropertyEditor | TextEdit |
| int/decimal | IntPropertyEditor | SpinEdit |
| DateTime | DateTimePropertyEditor | DateEdit |
| bool | BooleanPropertyEditor | CheckEdit |
| enum | EnumPropertyEditor | ComboBoxEdit |
| reference | LookupPropertyEditor | LookupEdit |
| image | ImagePropertyEditor | PictureEdit |
| color | ColorPropertyEditor | ColorEdit |
| rich text | RichTextPropertyEditor | RichEditControl |
| file | FileDataPropertyEditor | custom with OpenFileDialog |
Accessing DevExpress WinForms Controls
using DevExpress.ExpressApp.Win.Editors;
using DevExpress.XtraGrid.Views.Grid;
using DevExpress.XtraEditors;
public class CustomizeWinFormsController : ObjectViewController<ListView, MyObject> {
protected override void OnViewControlsCreated() {
base.OnViewControlsCreated();
if (View.Editor is GridListEditor gridEditor) {
GridView gridView = gridEditor.GridView;
gridView.OptionsView.ShowGroupPanel = false;
gridView.OptionsView.ShowFooter = true;
foreach (GridColumn col in gridView.Columns) {
if (col.FieldName == "Amount") {
col.Summary.Add(SummaryItemType.Sum, "Amount", "{0:C2}");
}
}
}
}
}
public class DetailViewController : ObjectViewController<DetailView, MyObject> {
protected override void OnViewControlsCreated() {
base.OnViewControlsCreated();
var nameEditor = View.FindItem("Name") as StringPropertyEditor;
if (nameEditor?.Control is TextEdit textEdit) {
textEdit.Properties.CharacterCasing = CharacterCasing.Upper;
}
}
}
Layout Customization
Via Model Editor (preferred)
Path: Views > <ClassName>_DetailView > Layout
Drag-and-drop property editors into groups, tabs, and columns.
Programmatic Layout (from Controller)
using DevExpress.ExpressApp.Win.Layout;
using DevExpress.XtraLayout;
public class LayoutController : ObjectViewController<DetailView, MyObject> {
protected override void OnViewControlsCreated() {
base.OnViewControlsCreated();
if (View.Control is DevExpress.ExpressApp.Win.Layout.XafLayoutControl layoutControl) {
var root = layoutControl.Root;
}
}
}
Background Workers (Thread Safety)
public class LongOperationController : ViewController {
private SimpleAction longAction;
public LongOperationController() {
longAction = new SimpleAction(this, "LongOp", PredefinedCategory.View) {
Caption = "Run Long Operation"
};
longAction.Execute += LongAction_Execute;
}
private void LongAction_Execute(object sender, SimpleActionExecuteEventArgs e) {
var worker = new BackgroundWorker { WorkerReportsProgress = true };
worker.DoWork += (s, args) => {
Thread.Sleep(3000);
args.Result = "Done";
};
worker.RunWorkerCompleted += (s, args) => {
if (args.Error != null)
throw new UserFriendlyException(args.Error.Message);
View.ObjectSpace.Refresh();
Application.ShowViewStrategy.ShowMessage(args.Result.ToString());
};
worker.RunWorkerAsync();
}
}
IMPORTANT: Never access IObjectSpace, View, Frame, or XAF objects from the DoWork handler — they are not thread-safe.
Splash Screen
public class MySplashScreen : ISplashScreen {
private SplashScreenForm form;
public void Start() {
form = new SplashScreenForm();
form.Show();
}
public void Stop() {
form?.Invoke(() => form.Close());
form = null;
}
public void SetDisplayText(string displayText) {
form?.Invoke(() => form.UpdateStatus(displayText));
}
}
protected override void CreateDefaultObjectSpaceProvider(CreateCustomObjectSpaceProviderEventArgs args) {
base.CreateDefaultObjectSpaceProvider(args);
SplashScreen = new MySplashScreen();
}
WinForms Navigation
var detailView = Application.CreateDetailView(objectSpace, targetObject);
Application.ShowViewStrategy.ShowView(
new ShowViewParameters(detailView), new ShowViewSource(Frame, null));
Printing / Print Preview
using DevExpress.ExpressApp.ReportsV2;
var reportController = Frame.GetController<ReportServiceController>();
reportController.ShowPreviewAction.DoExecute(reportData);
if (View.Editor is GridListEditor editor) {
editor.GridView.ShowPrintPreview();
}
Source Links