variable in iframe with zk - iframe

i have a for each in my zk page, and in the each i am creating a column, and in my column i need add a iframe, and to each frame i need pass as variable the label of the column.
I have something like:
<zk>
<window title="Dynamic Columns" border="normal" width="1824px" apply="org.zkoss.bind.BindComposer" viewModel="#id('vm') #init('pkg$.DynamicColumnModel')">
<grid >
<columns>
<column forEach="${vm.columnList}" label="${each}">
<iframe
src="test.zul" />
</column>
</columns>
</grid>
</window>
</zk>
But i have an error when i include the page, and my first problem is that i do not know how can i pass a variable to each iframe.
And my java is something like:
public class DynamicColumnModel {
private List<String> columnList = new ArrayList<String>();
private String texto="123";
#Init
public void init(){
columnList.add("Dynamic Col A");
columnList.add("Dynamic Col B");
columnList.add("Dynamic Col C");
columnList.add("Dynamic Col D");
}
public List<String> getColumnList() {
return columnList;
}
public void setColumnList(List<String> columnList) {
this.columnList = columnList;
}
public String getTexto() {
return texto;
}
public void setTexto(String texto) {
this.texto = texto;
}
#Command
public void mensaje(){
}
}
Thanks

If your each is a String, which it appears to be as you set it as the column label, just go ahead and pass it as a URL parameter to the iframe.
<window apply="org.zkoss.bind.BindComposer"
viewModel="#id('vm') #init('pkg$.DynamicColumnModel')">
<grid >
<columns>
<column forEach="${vm.columnList}" label="${each}">
<iframe src="test.zul?myValue=${each}" />
</column>
</columns>
</grid>
</window>
Note that when you are using an iframe component, you are stepping outside ZK. True, the iframe itself points to a ZK page, but it's a not within the same ZK environment. The iframe could just as easily include www.google.com and so there is no specific ZK support for passing values to ZK pages included in this manner.
If you're only including ZK pages and want to pass information to these pages more fluidly, you'll want to use ZK's include tag. Have a look at the documentation on how to pass values to included ZK pages.
Edit
If going the iframe route, you can access URL parameter values from test.zul using ZK's Execution class:
Execution execution = Executions.getCurrent();
execution.getParameter("myValue");

Related

Data Binding part of a label in xamarin forms

I am using Label in Xamarin forms.
I got to display a text which is basically a sentence but part of that string contains a number which I get from an api call and rest of the string is fixed.
I want to use data binding to set that part.
Example :
Text could be like : "You can win {0} dollars for sure"
{0} value comes from api and want to use data binding to bind it.
Need the syntax to be used to bind this kind of string.
You can use modle bind to data in your label.Just like this:
in xaml :
<Label Text="{Binding Name,StringFormat='You can win {0} dollars for sure'}"
HorizontalOptions="Center"
VerticalOptions="CenterAndExpand" />
in ContentPage, should bind context:
nativeDataTemple = new NativeDataTemple();
BindingContext = nativeDataTemple;
and Molde(NativeDataTemple you custom) should contain the binding property,like this:
private string name = "520";
public string Name
{
set
{
if (name != value)
{
name = value;
OnPropertyChanged("Name");
}
}
get
{
return name;
}
}
and in your modle ,when Name value change in the background,add INotifyPropertyChanged to the modle,and method
protected virtual void OnPropertyChanged(string propertyName)
{
PropertyChanged?.Invoke(this, new PropertyChangedEventArgs(propertyName));
}
then where you want change the data ,jusst do that:
nativeDataTemple.Name = "550";
if have problem ,you can refer to thisOfficial document
use spans within a Label
<Label>
<Label.FormattedText>
<FormattedString>
<Span Text="You can win " />
<Span Text="{Binding DollarAmount}" />
<Span Text=" dollars for sure." />
</FormattedString>
</Label.FormattedText>
</Label>

Hybris HMC: adding a button to ToolBarChip / Editor window next to the save button

I'm working with Hybris 5.6 and I'm trying to add a button in the editor area right next to the save/reload/delete buttons.
How can I add a button to the ToolBarChip like in the example below?
It's quite possible to add a new action (label) to the toolbar of HMC, however it's not so recommended as it may result some issues while the migration.
First, add the following snippet to your **/hmc.xml :
<type name="AbstractOrder" mode="append">
<organizer mode="append" >
<editor>
<tab name="payment_and_delivery" position="2" mode="append">
<section name="deliveryadministration" mode="append" >
<table>
<tr>
<td width="16px">
</td>
<td>
<!-- here is the interesting part -->
<action type="item"
classname="com.foo.bar.MyNewAction"
name="action.my_new_action"
toolbaricon="my_new_action"
icon="images/icons/my_new_action_icon.gif"
autosave="true"
showtoolbarlabel="true"
hidebutton="true"
/>
</td>
</tr>
</table>
</section>
</tab>
</editor>
</organizer>
</type>
Then, define the new action to be performed when the new label is clicked :
Add a new class called MyNewAction.java that extends from ItemAction and implement the method ActionResult perform(ActionEvent event) :
public MyNewAction extends ItemAction {
#Override
public ActionResult perform(ActionEvent actionEvent) throws JaloBusinessException {
//what the new action should do here ...
}
}
Note : you could override other interesting methods to be triggers while the action is possessing like : boolean needConfirmation() or String getConfirmationMessage() ...
The result would be like this :

Binding to selection of ViewModel

I'm trying to bind my ListBox to a selection of my ViewModel, because I have multiple ListBoxes in a Pivot and I don't want to type out the entire Page for each property. To illustrate my issue, here's a small sample:
XAML:
<DataTemplate x:Key="PropertyTemplate">
<StackPanel>
<TextBlock Text="{Binding Label}" />
<TextBlock Text="{Binding Value}" />
</StackPanel>
</DataTemplate>
<controls:Pivot>
<controls:PivotItem>
<ListBox ItemsSource="{Binding PropertySelectionOne}" ItemTemplate="{StaticResource PropertyTemplate}" />
</controls:PivotItem>
<controls:PivotItem>
<ListBox ItemsSource="{Binding PropertySelectionTwo}" ItemTemplate="{StaticResource PropertyTemplate}" />
</controls:PivotItem>
</controls:Pivot>
ViewModel:
public class SomeViewModel
{
private Property _propOne;
public Property PropOne
{
get { return _propOne; }
set { _propOne = value; NotifyPropertyChanged("PropOne"); }
}
private Property _propTwo;
public Property PropTwo
{
get { return _propTwo; }
set { _propTwo = value; NotifyPropertyChanged("PropTwo"); }
}
private Property _propThree;
public Property PropThree
{
get { return _propThree; }
set { _propThree = value; NotifyPropertyChanged("PropThree"); }
}
}
So basically I want to bind my ListBoxes to PropertySelectionOne and PropertySelectionTwo, which would contain references to a selection of the properties in my ViewModel. For instance, PropertySelectionOne could include PropOne and PropTwo and PropertySelectionTwo could include PropTwo and PropThree.
Is there a simple way to "group" these properties to a new property to bind against without changing the architecture of my application?
Thanks
If you've got different properties to be displayed from the same date type in different list boxes, then arguably you need to split your view model, but you say you don't want to change the architecture of your application, which is your choice.
So, what you need to do is to provide a different ItemTemplate for each ListBox that defines which properties and how you want to display in each ListBox. Then you can bind the ItemsSource for all of the list boxes to the same data source but they will present different properties according to the ItemTemplate.
Not sure how familiar you are with these concepts, but you know that ItemsSource needs to be a collection of your data instances (SomeViewModel?), right?

How add a global "IsReadOnly" style to all DataGridTextColumns

I currently have a ResourceDictionary file for my WPF application, which pretty much adds every style that I could possibly want throughout all of my application's DataGrids.
Except one.
How can I add a global "IsReadOnly" setter, for all of my DataGrid's DataGridTextColumn columns ?
Basically, I use a few DataGrids, and if I want to display read-only data in a particular column, I'll just display the data using a DataGridTextColumn:
<WPFtoolkit:DataGridTextColumn Binding="{Binding Path=DOB,StringFormat='dd/MMM/yyyy'}" Header="DOB" Width="120" />
However, if I have a column which has editable data, then I'll use a DataGridTemplateColumn instead.
<WPFtoolkit:DataGridTemplateColumn xHeader="Department Name" >
<WPFtoolkit:DataGridTemplateColumn.CellTemplate>
<DataTemplate>
<ComboBox Width="175"
ItemsSource="{Binding Source={StaticResource AllDepartmentsDataSource}}"
SelectedValue="{Binding DepartmentID}" SelectedValuePath="DepartmentID" DisplayMemberPath="DepartmentName"
VerticalAlignment="Center"
>
</ComboBox>
</DataTemplate>
</WPFtoolkit::DataGridTemplateColumn.CellTemplate>
</tWPFtoolkit:DataGridTemplateColumn>
The problem is, for every one of my DataGridTextColumns, I specifically need to add the IsReadOnly parameter, otherwise the user can (incorrectly) edit that data:
<WPFtoolkit:DataGridTextColumn IsReadOnly="True" Binding="{Binding Path=DOB,StringFormat='dd/MMM/yyyy'}" Header="DOB" Width="120" />
Is there a way to add this "IsReadOnly" setting globally, in the ResourceDictionary file, to all of my DataGridTextColumns...?
I can add global styles to DataGrid, DataGridColumnHeader, DataGridRow, and DataGridCell, but if I try to define a style with a TargetType of DataGridTextColumn, then Visual Studio complains that DataGridTextColumn is not derived from a FrameworkElement or FrameworkContentElement.
<Style TargetType="{x:Type WPFToolkit:DataGridTextColumn}">
<Setter Property="IsReadOnly" Value="True"/>
</Style>
I can add IsReadOnly to the Grid style, but this makes all columns uneditable !
Can anyone think of an quick and easy way to add this simple property to the DataGridTextColumns ?
Update:
My solution has been (reluctantly) to add a Loaded handler to each of my DataGrids, which runs this code:
void grdGrid_Loaded(object sender, RoutedEventArgs e)
{
DataGrid dg = (DataGrid)sender;
foreach (DataGridColumn col in dg.Columns)
{
DataGridTextColumn textCol = col as DataGridTextColumn;
if (textCol != null)
{
textCol.IsReadOnly = true;
}
else
{
// This DataGridColumn isn't of type "DataGridTextColumn", so do nothing.
}
}
}
You could, of course, put this in your own DataGrid-inherited control, rather than repeating it for each of your DataGrids.
(Sigh.)
Why didn't MS make IsReadOnly an attachable property..? It would've made life so much easier!

How do I find a Silvlerlight object on an Asp.Net page using Microsoft UI Automation testing?

I have an object on my asp.net page hosting a Silverlight xap (in my particular case it is in an IFrame, but I'm curious about regular objects as well). I can find the element in UI Spy, but the name just says "Silverlight Control". Trying to find that AutomationElement in my automated test is unsuccessful (control is null every time). Is there a setting in the Silverlight code or in the html that would help? How can I distinguish it if there are multiple Silverlight controls on the same page?
<object id="silverlightClient" style="display:none;" data="data:application/x-silverlight-2," type="application/x-silverlight-2">
<param name="source" value="../../ClientBin/SilverlightApplication.xap"/>
<param name="onerror" value="onSilverlightError" />
<param name="background" value="#00000000" />
<param name="minRuntimeVersion" value="4.0.41019.0" />
<param name="autoUpgrade" value="true" />
<param name="windowless" value="false" />
</object>
TreeWalker tw = new TreeWalker(new System.Windows.Automation.PropertyCondition(AutomationElement.NameProperty, "Silverlight Control));
AutomationElement control = tw.GetFirstChild(ancestor);
UI Spy
Identification
ClassName: "MicrosoftSilverlight"
ControlType: "ControlType.Window"
Culture: "(null)"
AutomationId: "71857844"
LocalizedControlType: "window"
Name: "Silverlight Control"
ProcessId: "7636 (iexplore)"
RuntimeId: "42 2163886"
IsPassword: "False"
IsControlElement: "True"
IsContentElement: "True"
EDIT: added image, I also realized that the object is inside of an IFrame.
UISpyImage - title name removed
I've created some extension methods to make working with AutomationElement somewhat easier. I've pasted the relevant ones below, but you can read more about them here.
I'm assuming you've got a reference to the root IE window. If not, but you know it's Process Id you can find it like so:
var ieWindow = AutomationElement.RootElement.FindChildByCondition(new PropertyCondition(AutomationElement.ProcessIdProperty, ieProcessId));
Assuming there's only one Frame open in IE, and a single Silverlight control on it, you can then do:
var silverlightControl = ieWindow.FindDescendentByClassPath(
new[]{
"Frame Tab",
"TabWindowClass",
"Shell DocObject View",
"Internet Explorer_Server",
"MicrosoftSilverlight",
});
If you have more than one Silverlight control, I don't know of a way to distinguish them through UIAutomation. I would try dropping the "MicrosoftSilverlight" entry from the Class path above, so that you get a reference to the Explorer page. Then use
AutomationElement.FindAll(TreeScope.Children, new PropertyCondition(AutomationElement.ClassNameProperty, "MicrosoftSilverlight"))
to find all the SilverlightControls, then probe them each in turn locate some element within them that allows you to distinguish between them.
Here are the extension methods:
public static class AutomationExtensions
{
public static AutomationElement FindDescendentByClassPath(this AutomationElement element, IEnumerable<string> classNames)
{
var conditionPath = CreateClassNameConditionPath(classNames);
return element.FindDescendentByConditionPath(conditionPath);
}
public static AutomationElement FindDescendentByConditionPath(this AutomationElement element, IEnumerable<Condition> conditionPath)
{
if (!conditionPath.Any())
{
return element;
}
var result = conditionPath.Aggregate(
element,
(parentElement, nextCondition) => parentElement == null
? null
: parentElement.FindChildByCondition(nextCondition));
return result;
}
public static AutomationElement FindChildByCondition(this AutomationElement element, Condition condition)
{
var result = element.FindFirst(
TreeScope.Children,
condition);
return result;
}
public static IEnumerable<Condition> CreateClassNameConditionPath(IEnumerable<string> classNames)
{
return classNames.Select(name => new PropertyCondition(AutomationElement.ClassNameProperty, name, PropertyConditionFlags.IgnoreCase)).ToArray();
}
}

Resources