I am having the following situation:
CollectionView, each item is Border, that contains other controls.
When selected, the VisualState of the Border changes to selected. The child controls however do not have a change in their state.
Is there an easy way to link/pass those VisualStates to all child controls?
(cascade, 2,3,4 and more levels deeper)
Edit: I know how to use Triggers, Setters in Styles and other approaches to change the UI of the application. The question is specifically for changing the VisualState of the nested VisualElements. Cannot find anything anywhere on this matter.
You can try to set state on multiple elements.
Visual states could be attached to and operated on single elements. And it's also possible to create visual states that are attached to a single element, but that set properties on other elements within the same scope. This avoids having to repeat visual states on each element the states operate on.
The following example shows how to set state on multiple objects, from a single visual state group:
<StackLayout>
<Label Text="What is the capital of France?" />
<Entry x:Name="entry"
Placeholder="Enter answer" />
<Button Text="Reveal answer">
<VisualStateManager.VisualStateGroups>
<VisualStateGroup x:Name="CommonStates">
<VisualState x:Name="Normal" />
<VisualState x:Name="Pressed">
<VisualState.Setters>
<Setter Property="Scale"
Value="0.8" />
<Setter TargetName="entry"
Property="Entry.Text"
Value="Paris" />
</VisualState.Setters>
</VisualState>
</VisualStateGroup>
</VisualStateManager.VisualStateGroups>
</Button>
</StackLayout>
Note: Property paths are unsupported in Setter elements that specify the TargetName property.
You can also try to define custom visual states, for more information, you can check: Define custom visual states .
Related
I have a TableView in which I render form controls for data editing.
However, as soon as the Entry control receives focus, the ViewCell seemingly collapses, leaving only the section title and separator borders visible:
<TableView Intent="Data">
<TableRoot>
<TableSection Title="Details">
<ViewCell>
<Grid ColumnDefinitions="0.5*,0.5*">
<Label Text="Manufacturer" />
<Entry Text="{Binding Manufacturer}" Grid.Column="1" />
</Grid>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
Initial state:
After tapping the Entry element:
I've tried setting a specific height for the Grid and the Entry control, but I get the same result regardless.
Am I missing something obvious here? 🤔
It's a bug in .NET MAUI: https://github.com/dotnet/maui/issues/10322
I ran into this a while ago and reported it. For now, I have created my own table using a Grid.
You can change The TableView HeightRequest property to a large number such as 700.
This is a temporary workaround until the bug is fixed.
<TableView HeightRequest="700">
<TableRoot>
<TableSection>
<!-- Your code goes here -->
</TableSection>
</TableRoot>
</TableView>
But, in most scenarios, you don't know what the Height is so you could set it dynamically in your code behind.
Page constructor:
public MainPage()
{
InitializeComponent();
// if you want your table height to fit half of the page
Table.HeightRequest = this.Height / 2;
// Rest of logic...
}
Xaml:
<TableView x:Name="Table">
<TableRoot>
<TableSection>
<ViewCell>
<Label Text="Example"/>
</ViewCell>
</TableSection>
</TableRoot>
</TableView>
<ObjectListItem
title="{i18n>uBOMItem}: {Item} Component: {ComponentDesc}"
number="{ComponentNo}"
>
I am using sap.m.ObjectListItem. While binding, I need tab space between {Item} & {ComponentDesc}.
E.g. like \t
Currently, sap.m.ObjectListItem does not support rendering whitespace for title.
And I agree with alexP's answer that it's not clean to combine multiple labels ("{i18n>uBOMItem}:" and "Component:") into one.
That being said; if it's really necessary to do so, however, you'll need to extend ObjectListItem.
Example: https://embed.plnkr.co/WaMaP4wqMevsjMxX
Internally, ObjectListItem renders its title from sap.m.Text. The Text control has a public property called renderWhiteSpaceapi which we can use to allow tabs to be rendered.
ObjectListItem is only for one value. In your case it's better to use CustomListItem.
<CustomListItem>
<HBox width="100%">
<VBox>
<Label emphasized="true" text="{i18n>uBOMItem}: {Item}" />
</VBox>
<VBox class="sapUiSmallMarginBegin">
<Label emphasized="true" text="Component: {ComponentDesc}" />
</VBox>
<VBox width="50%" justifyContent="End">
<ObjectNumber number="{ComponentNo}" />
</VBox>
</HBox>
</CustomListItem>
It's not clean to output two data bindings from your model in one label, text or similar. You should split the output. In case of an i18n label and a data binding in one control i would make a exception.
I have a label in my rg.plugins popup page and I want to change the text color of the label when doing an action.
I try to add an id to the label in xaml, but that is not possible. Is there any way to change the label text color from xaml.cs class.
Thanks in advance
Some sample code would help understand what the issues might be. I assume by rg.plugins, you're referring to: https://github.com/rotorgames/Rg.Plugins.Popup so I will answer accordingly.
It looks like it takes standard xaml and displays that in a dialog type popup. Your options for styling should be the same as any other:
Change color directly in xaml. <Label Text="This is some text" TextColor="Blue" />
Change it via a binding. TextColor="{Binding ColorThatIWant}" Where the page's BindingContext has been set to an object that has a public property or binding property of ColorThatIWant. Don't forget to implement INotiftyPropertyChanged if you want forms to react to property changes.
Set the value in code behind. MyLabel.TextColor = UIColor.Blue; where the label has a name value set. <Label x:Name="MyLabel" Text="This is some text" />
Use style dictionaries to set the value. <Label Text="This is some text" Style="{StaticBinding MyLabelStyle}"/> with a style of:
<Style x:Key="MyLabelStyle" TargetType="Label">
<Setter Property="TextColor" Value="Blue" />
</Style>
I'm working in a web application using ZK. I'm struggling with a window where I need to render a grid with as much rows as the user specifies. It should be something like:
<grid>
<columns>
<column width="150px"/>
<column width="350px"/>
</columns>
<rows>
<row>
<cell>
<label value="Rows to add"/>
</cell>
<cell>
<textbox id="txt_rowamount"/>
</cell>
</row>
</rows>
</grid>
<grid id="grid">
<columns>
<column width="100px" label="Field 1" align="center"/>
<column width="100px" label="Field 2" align="center"/>
<column width="100px" label="Field 3" align="center"/>
</columns>
<rows id="rows" forEach="${rowModelList}">
<row>
<cell>
<textbox value="${each.field1}" />
</cell>
<cell>
<textbox value="${each.field2}" />
</cell>
<cell>
<textbox value="${each.field3}" />
</cell>
</row>
</rows>
</grid>
<button id="btn_generate" label="Generate Rows"/>
So, if you type 4 in txt_rowamount a grid with 4 row components and 3 textbox components in each row. The textboxes should be empty and when I complete every textbox the user input should be binded to fieldN of every rowModel item, do I make myself clear?
I'm trying with something like this in the composer:
private ListModel<RowModel> rowModelList;
#Autowired
private Grid grid;
#Override
public void doAfterCompose(final Window component) throws Exception {
super.doAfterCompose(component);
rowModelList = new ListModelList<>();
grid.setVisible(false);
}
public void onClick$btn_generate() {
// TODO Add four empty elements to rowModelList
grid.setVisible(true);
}
Being RowModel like
public class RowModel {
private String field1;
private String field2;
private String field3;
// ommited constructors, getters and setters
}
I believe that the approach should be MVVM instead of the current MVC but I don't know how to do this. Besides, I don't know if you can mix the approachs in the same application and what are the advantages and disadvantages of doing that.
I've seeing the ZK grid demos but all of them are using already populated objects to render the tables, so it's not useful to me.
If someone can give me a hand in this issue, it would be greatly appreciated. If you need more information on the code or the requirements for this problem, please comment it out.
Thanks in advance for your answers.
It seems there's a lot missing in your current attempt, so I'll try to fill the gaps.
If impatient here a runnable example on zkfiddle.
Since you were talking about binding component attributes to model values I'd suggest using ZK's DataBinding which integrates nicely into the MVVM development pattern (sorry for the link, but that's not a one-liner).
In any case the example illustrates how to combine ZK features such as (ListModelList with templates, Property-/Command-Binding) into a simple dynamic UI.
As you can see in code, adding, (re)moving a row inside the model requires rudimentary operations (the grid will update its child-rows automatically):
rows.add(new RowModel(...));
rows.remove(row);
Since the ListModelList is assigned to the <grid> component via #init(vm.rows), the grid will listen to changes to the ListModel and add remove grid-rows accordingly. It uses the <template name="model" var="rowModel"> to render new rows when added to the model. The template variable rowModel variable represents the rowModel object. (more on that in our documentation)
I hope this information is not overwhelming ... if so please let me know.
BTW: the forEach-attribute you were trying to use previously is used for static ui composition (at zul parse time) where no dynamic control is required. For dynamic cases use ListModel(List) in combination with templates.
Robert
I have listBox modified for check boxes. I would like to bind the selectedItem to the check so that I can use $WPFlbSiteList.SelectedItem as the basis of selecting items that are checked.
Basically, I have generated a list I need the checks to equate to the selected item. This selected item also needs to work in a multi selection capacity rather than one at a time.
<ListBox x:Name="lbSiteList" SelectionMode="MultiExtended" Margin="355,45,411,1014" ItemsSource="{Binding .}">
<ListBox.ItemTemplate>
<DataTemplate>
<CheckBox Content="{Binding .}" IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected}" Margin="2,2,0,0"/>
</DataTemplate>
</ListBox.ItemTemplate>
</ListBox>
My function to write to the console which of my checked items are selected.
$WPFbtnUpdate.Add_Click({
#List the sites that are ticked
foreach ($WPFlbSiteList.Items in $WPFlbSiteList){
$x=$WPFlbSiteList.SelectedItems
write-host $x
}
})
As noted in the comments you can bind the checkbox IsChecked value to IsSelected of it's relative ancestor (the listbox) with:
<CheckBox IsChecked="{Binding RelativeSource={RelativeSource AncestorType={x:Type ListBoxItem}}, Path=IsSelected" />
Your real issue, however, seems to be that you're using an invalid value for the ListBox' SelectionMode property.
In WPF, the valid selection modes are:
Extended - The user can select multiple consecutive items while holding down the SHIFT key.
Multiple - The user can select multiple items without holding down a modifier key.
Single - The user can select only one item at a time.