As I posted in an earlier article, Uiml.net allows us to connect the application logic with the user interface.
I showed that it’s possible to create a callback that listens to certain events, optionally only coming from a specific part. In these callbacks we can examine the part that has sent the event using the Uiml.net API.
But is it also possible to modify that part?
Of course we could operate on the widget-set specific user interface object (e.g. a System.Windows.Forms.Button), but that would require different code for each target widget set. Here is how we would change a button’s label when it is clicked using this approach:
public class ModifyTest { public ModifyTest() { ... // connect only to the hello button uimlDoc.Connect(this, "b_hello"); ... } [UimlEventHandler("ButtonPressed")] public void OnButtonClicked(Part sender, UimlEventArgs e) { // get the concrete UI object System.Windows.Forms.Button b = (System.Windows.Forms.Button) sender.UiObject; // change its text to 'Do it again!' b.Text = "Do it again!"; } } |
Uiml.net provides a property setter interface that can apply any property. We only need the renderer instance in order to access it. We could use this API to modify the user interface in a generic way, if we rely on a shared class and property among all widget set vocabularies. In our example, the Button class exists for all vocabularies that Uiml.net supports, and has a label property in each vocabulary.
Let’s have a look at the generic solution. We only list the important code:
public class ModifyTest { IRenderer _renderer; ... [UimlEventHandler("ButtonPressed")] public void OnButtonClicked(Part sender, UimlEventArgs e) { // create a label property Property p = new Property(); p.PartName = sender.Identifier; p.Name = "label"; // set its value to 'Do it again!' p.Value = "Do it again!"; // apply the property on the sender part _renderer.PropertySetter.ApplyProperty(sender, p); } } |