Jump to: navigation, search

Changes


Property Based Content Filters

2,781 bytes added, 09:53, 27 June 2024
Refactoring of article layout for clarity. Added some missing xaml impls
A collection of property-based content filtering criteria can be applied to child object lists. {{Version/WinXSince|2.6.1}} Some common use cases are as follows.* A user The UI can enter a text be customized to accept user inputs as filter criteria, and reduce the entire child list to a sub -list of those whose certain based on property display values that contain that text;* A customizer . Each filter is 'attached' to a single metaproperty, and multiple filters can create UI that presents several text input fields serving as such filters, with each be applied to a different propertyat once.
{{Hint|When multiple filters are used at the same time, they are combined with "logic and".}}
For exampleperformance/usability reasons, the result list is not immediately refreshed as one types in the text box. One can customize Instead, it only happens after the ChildArea ReloadChildListCommand is triggered. However, note that these content-based filters:* Require a custom [[SYSCLS_CHILDAREATEMPLATE|Child Area template name]] to work. This customizing will not work applied to include the followingUBIKChildArea.* Work directly on the Children.Items collection. While filters are active, anything derived from this collection (such as Children.Items.Count or custom datasources like [[XAML_Changes_in_UBIK_WinX_3.5#Filtering_by_expressions|ListCollectionView]] / [[Xamarin_XAML#Content_filtering|sfDataSourceExt]]) will also be affected.<br><br> == Usage ==For simple text input, it is enough to create a text input control with a TwoWay relationship to the Children.Filter[x]. However, the TwoWay binding doesn't always work well with more advanced implementations, such as selection. In such cases, the alternative is to use the UpdatePropertyFiltersCommand to supply the filter criteria. Both approaches are described below=== Text Input ===<tabs> <tab name="UWP">
<source lang = "xml">
<Grid>TextBox <Border Background="#8000488E" Visibility="{Binding Children.Filters[SomePropertyName], Converter={StaticResource NullObjOrEmptyStrColConverter}}" /> <Border Background="#90707070" Visibility="{Binding Children.Filters[SomePropertyName], Converter={StaticResource NullObjOrEmptyStrVisConverter}}" /> <TextBox Text="{Binding Children.Filters[SomePropertyName], Mode=TwoWay, Converter={StaticResource FilterCriterionToValueConverter}}" PlaceholderText="SomePropertyName" BorderThickness="0" Foreground="White" Background="Transparent" /> </Grid>
</source>
</tab>
<tab name="Xamarin">
<source lang = "xml">
<Entry
Placeholder="Filter by Name"
Text="{Binding Children.Filters[DESCR], Mode=TwoWay, Converter={StaticResource FilterCriterionToValue}}"/>
</source>
</tab>
</tabs>
This is shown as a single text box. The two way binding on Text allows the entered text (case insensitive) to be used as the filter value on property "SomePropertyName" (case sensitive).
<br>
When multiple filters are used at the same time, they are combined with "logic and". For performance/usability reasons, the result list is not immediately refreshed as one types in the text box. Instead, it only happens after the [[ReloadChildListCommand]] is triggered. {{Hint|The Borders in the example are not mandatory. They serve as indicators of whether a filter is currently applied on the result list. The PlaceHolderText is optional as well.}} === UpdatePropertyFiltersCommand {{Version/XamarinSince|1.2}} Selection === The above mentioned two way binding doesnSelection is trickier to achieve than direct input, as often a metaproperty't always work well with all controls and complex bindings. In such cases, s actual value might differ from the alternative text that is to use the UpdatePropertyFiltersCommand to supply the filter criteriadisplayed for that value. Just think of integer-based statuses, or GUID properties
<tabs>
  <tab name="XamarinUWP">
<source lang = "xml">
<Grid xmlnscontrols:ctrls="clr-namespaceComboBoxExt x:UBIK.CPL.Controls;assemblyName=UBIK.CPL"ComboBox" xmlns:classes PlaceholderText="clr-namespace:UBIK{Binding Children.CPLFilters[STATUSCOLOR].Classes;assemblyValue, FallbackValue=UBIK.CPL'SELECT'}"> <ctrls:PickerExtDisplayMemberPath="DisplayText" x:Name SelectedValuePath="FilterDisplayText" ItemsSource SelectedValue="{Binding PropertiesChildren.AllItemsFilters[QUERYSTATUSCOLOR].LinkedLevel.Children.ItemsValue}" ItemDisplayBinding SelectedValueExt="{Binding HeaderChildren.Filters[STATUSCOLOR].Value}" SelectionChangedCommand ItemsSource="{Binding Children.UpdatePropertyFiltersCommandItems[1].Properties.AllItems[STATUSCOLOR].MetaProperty.SelectiveList, Converter={StaticResource SelectiveListToItemsConverter}}">  <interactivity:Interaction.Behaviors> SelectedValuePath<core:EventTriggerBehavior EventName="UIDSelectionChanged"> SelectedValue <core:InvokeCommandAction Command="{Binding Children.Filters[STA].Value, Mode=OneWayUpdatePropertyFiltersCommand}"> <ctrlscore:PickerExtInvokeCommandAction.SelectionChangedCommandParameterCommandParameter> <classescontrols:KeyValueList> <classescontrols:KeyValueParameter Key="ClearPropertyFilters" Value="false" /> <classescontrols:KeyValueParameter Key="STASTATUSCOLOR" Value="{Binding Path=SelectedItem.UIDDisplayText, SourceElementName={x:Reference Filter}ComboBox}" /> </classescontrols:KeyValueList> </ctrlscore:PickerExtInvokeCommandAction.SelectionChangedCommandParameterCommandParameter> </core:InvokeCommandAction> </core:EventTriggerBehavior> </ctrlsinteractivity:PickerExtInteraction.Behaviors></Gridcontrols:ComboBoxExt>
</source>
</tab>
Note that several elements are required for this customization to work:* SelectedValuePath informs the control of which property should be supplied to the command as a filter criteria. This should match what is supplied in your KeyValueParameter.* DisplayMemberPath informs the control of which property should be visualized as the displaytext of your selection.* PlaceholderText binds to the same value as your SelectedValueExt to display the current selected item. This is a workaround for a failure of the ComboBox control to correctly display an active selection when the control is rendered. </tab> <tab name="UWPXamarin">Not yet available. </tab><source lang = "xml"> xmlns:ctrls="clr-namespace:UBIK.CPL.Controls;assembly=UBIK.CPL"xmlns:classes="clr-namespace:UBIK.CPL.Classes;assembly=UBIK.CPL">
<ctrls:PickerExt
x:Name="Filter"
ItemsSource="{Binding Properties.AllItems[QUERY].LinkedLevel.Children.Items}"
ItemDisplayBinding="{Binding Header}"
SelectionChangedCommand="{Binding Children.UpdatePropertyFiltersCommand}"
SelectedValuePath="UID"
SelectedValue="{Binding Children.Filters[STA].Value, Mode=OneWay}">
<ctrls:PickerExt.SelectionChangedCommandParameter>
<classes:KeyValueList>
<classes:KeyValueParameter Key="ClearPropertyFilters" Value="false" />
<classes:KeyValueParameter Key="STA" Value="{Binding Path=SelectedItem.UID, Source={x:Reference Filter}}" />
</classes:KeyValueList>
</ctrls:PickerExt.SelectionChangedCommandParameter>
</ctrls:PickerExt>
</source>
</tabs>
The example above uses a UBIK.CPL.Controls.PickerExt custom ComboBox/Picker control to display a list of query result objects (through the "QUERY" property's LinkedLevel)items. The UID chosen aspect of the of the selected object is then passed on as a part of the command parameter and later used as a filter criterion to filter for objects that have their "STA" property value containing the UID same the string. This approach makes use of the Children.UpdatePropertyFiltersCommand, which uses the following parameters:
* ClearPropertyFilters: Clear out all existing filters at the current level before executing the command. This is optional and defaults to false;
* All other parameters: Used KeyValue pairs used as filter criteria where the Keys are the names of the properties metaproperties by which you want to filter.
<br>
 
=== Evaluation Criteria ===
By default, the expression used for filtering is Content["PROPERTY_NAME"].DisplayValue.ToLower().Contains(FILTER_VALUE.ToLower())==true.
In other words, it checks whether the specified filter value (as string) is contained in the display value of the property.
By default, the expression used for filtering is Content["PROPERTY_NAME"].DisplayValue.ToLower().Contains(FILTER_VALUE.ToLower())==true. In other words, it checks whether the specified filter value (as string) is contained in the display value of the property.
In more advanced scenarios where a different type of comparison is needed, the example (or more specifically the one KeyValueParameter) can be extended into the following, e.g. comparing whether the specified filter value is equal to the value of the property.
<source lang = "xml">
<classes:KeyValueParameter Key="STA" Value="{Binding Path=SelectedItem.UID, Source={x:Reference Filter}, Converter={StaticResource FilterValueToCriterion}, ConverterParameter=Content[\&quot;\{0\}\&quot;].Value.ToString().Equals(\&quot;\{1\}\&quot;)\=\=true}" />
</source>
 
{{Hint|"&amp;quot;" and "\" are used for escaping the special characters in XAML and C# code respectively. "{0}" and "{1}" are placeholders and get replaced by the property name and the filter value. The end expression being executed in this example is <code>Content["PROPERTY_NAME"].Value.ToString().Equals(FILTER_VALUE)&#61;&#61;true</code>}}
{{Category<br><br> == UI Customizing == === Update Child List ===For performance/Version|2usability reasons, the result list is not immediately refreshed as one types in the text box.6Instead, it only happens after the ReloadChildListCommand is triggered.1 === Filtered Indicator ===You can also customize UI elements to indicate that filters are active.<source lang = "xml"><Border Background="#8000488E" Visibility="{Binding Children.Filters[SomePropertyName], Converter={StaticResource NullObjOrEmptyStrColConverter}}" /></source> UWP: The above border is shown when a filter is active.
[[Category:2.6.1|Property Based Content Filters]]
728
edits