所谓的动态UI就是指应用程序在运行时,通过程序动态生成UI,一般动态UI的应用场景如下
- 高度可配置的应用程序
- 门户整合的应用
- 定制和个性化
- . . . . . .
同时,还应具有对输入的数据进行动态验证的功能。
动态创建UI比在运行时实例化一个组件要复杂,这会受可视化设计工具的限制,而现实中的需求往往需要从数据库、XML或者用户偏好等数据源创建对应的用户界面。
动态创建用户界面可能会让编码比较难以维护,不过好处是能让程序更具弹性并适应不同的需求和内容的变更。
XWT对动态UI的支持
- 组件绑定: 组件绑定是数据绑定的一种形式,但是UI组件可以使用数据绑定源。
- 属性触发器。
- 数据触发器。
- 事件触发器。
属性触发器:
当组件属性修改时触发,用法:
<Button x:Style="CHECK" text="Unselected">
<Button.triggers>
<Trigger property="Selection" value="true">
<Setter property="Text" value="Selected"/>
</Trigger>
</Button.triggers>
</Button>
运行效果:
属性触发器还可以检测其他组件的变化,用法:
<Button Name="Button1" x:Style="CHECK" text="Unselected"/>
<Button x:Style="CHECK" text="Button State">
<Button.triggers>
<Trigger property="selection" value="true">
<Setter property="Text" value="selected" targetName="Button1"/>
</Trigger>
</Button.triggers>
</Button>
可以使用targetName属性指定目标组件,值为目标组件的Name属性。
数据触发器
当模型数据发生改变时,让UI进行调整
<Shell xmlns="http://www.eclipse.org/xwt/presentation" xmlns:x="http://www.eclipse.org/xwt"
xmlns:y="clr-namespace:org.eclipse.e4.xwt.tests.trigger.datatrigger"
x:Class="org.eclipse.e4.xwt.tests.trigger.datatrigger.EventHandler"
x:Name="Root" DataContext="{StaticResource myData}">
<Shell.layout>
<GridLayout numColumns="2" />
</Shell.layout>
<Shell.Resources>
<y:Person x:Key="myData" />
</Shell.Resources>
<Label text="Name" />
<Text x:style="BORDER" text="{Binding Path=name}">
<Text.layoutData>
<GridData horizontalAlignment="FILL" grabExcessHorizontalSpace="true" />
</Text.layoutData>
</Text>
<Button name="Button" x:style="SWT.CHECK" selection="{Binding Path=maried}">
<Button.triggers>
<DataTrigger binding="{Binding Path=maried}" value="false">
<Setter property="text" value="Alone" />
</DataTrigger>
</Button.triggers>
<Button.layoutData>
<GridData horizontalAlignment="FILL" grabExcessHorizontalSpace="true" />
</Button.layoutData>
</Button>
<Label></Label>
<Button text="person.setMaried" x:style="SWT.PUSH" SelectionEvent="clickButton"></Button>
</Shell>
通过DataTrigger标记可以将组件与数据上下文绑定
<Button.triggers>
<DataTrigger binding="{Binding Path=maried}" value="false">
<Setter property="text" value="Alone" />
</DataTrigger>
</Button.triggers>
在这个例子中将Person对象设置为了数据上下文.步骤如下:
<Shell xmlns="http://www.eclipse.org/xwt/presentation" xmlns:x="http://www.eclipse.org/xwt"
xmlns:y="clr-namespace:org.eclipse.e4.xwt.tests.trigger.datatrigger"
x:Class="org.eclipse.e4.xwt.tests.trigger.datatrigger.EventHandler"
x:Name="Root" >
......
<Shell.Resources>
<y:Person x:Key="myData" />
</Shell.Resources>
......
</Shell>
我们给按钮注册选择事件,在点击之后修改Person的属性,处理类:
package org.eclipse.e4.xwt.tests.trigger.datatrigger2;
import java.lang.reflect.InvocationTargetException;
import org.eclipse.core.databinding.observable.value.IObservableValue;
import org.eclipse.e4.xwt.XWT;
import org.eclipse.e4.xwt.metadata.IProperty;
import org.eclipse.swt.widgets.Event;
import org.eclipse.swt.widgets.Shell;
public class EventHandler {
protected void clickButton(Event event) throws Exception {
Shell shell = (Shell) XWT.findElementByName(event.widget, "Root");
Person person = (Person) XWT.getDataContext(shell);
IObservableValue observableValue = XWT.findObservableValue(shell, person, "maried");
observableValue.setValue(!person.isMaried());
System.out.println("person.isMaried() = " + person.isMaried());
}
}
- 使用XWT.findElementByName查找到Shell组件
- 然后获取数据上下文对象Person实例
- 更改Person的maried属性
- 使用XWT.findObservableValue查找数据绑定类
- 只需要调用一次IObservableValue.getValue()方法就会更新UI值了。
事件触发器
<Composite xmlns="http://www.eclipse.org/xwt/presentation"
xmlns:x="http://www.eclipse.org/xwt">
<Composite.layout>
<GridLayout numColumns="1"/>
</Composite.layout>
<!-- The width of this button is animated. -->
<Button x:Style="SWT.CHECK" Text="Trigger">
<Button.Triggers>
<EventTrigger RoutedEvent="SelectionEvent">
<Setter Property="Visible" Value="False" />
</EventTrigger>
</Button.Triggers>
</Button>
</Composite>