🕓 12 MIN Welcome to 2024 and …
One of the most significant aspects of the XAML-based applications is the concept of lookless controls. This means that controls can be restyled without changing the behaviour. The Windows App SDK and Uno Platform provide out-of-the-box styles for GridView and ListView controls, offering a great starting point for working with these controls. In this post, Nick Randolph digs into being able to disable individual items.
The default style for these controls includes a Disabled state, which is applied to each item when the IsEnabled property on the control is set to true. However, in some scenarios, it may be necessary to disable individual items. Unfortunately, unlike many other aspects of the GridView and ListView controls, there’s no easy way to disable individual items. Let’s dig into this and look at why it’s difficult and a workaround that can be used. For the rest of this post, we will focus on the GridView, but everything we cover can be applied equally to the ListView control.
The GridView control has several templates that control how the control is styled. A ControlTemplate for the GridView defines things like the position and style of scrollbars. The arrangement of items is governed by the ItemsPanelTemplate (the ItemsPanel property). The ItemTemplate controls the layout of each item. Each item is wrapped in a GridViewItem, and the ControlTemplate for the GridViewItem defines the various visual states for the item, such as Selected, Pressed and Disabled.
When the GridView is disabled, the each of the GridViewItem transitions to the Disabled visual state. In order to disable an individual item, the challenge is to switch the respective GridViewItem into the Disabled state. This requires accessing the GridViewItem in order to set the IsEnabled property to false.
Accessing the GridViewItem isn’t straightforward since the lifecycle of each GridViewItem is managed by the GridView. However, there is a point where we can access the GridViewItem, which is at the point where it’s applying the ItemTemplate for the corresponding item that’s to appear in the GridView. At this point the GridViewItem is already created and it’s template has been applied. Normally, an instance of the ItemTemplate is created (or recycled) and is used to layout the item. However, if we use an ItemTemplateSelector, we have an opportunity to interact with the GridViewItem before it applies the ItemTemplate.
In the following code, the CustomTemplateSelector is used to setup a Binding between the IsEnabled property on the GridViewItem (actually on SelectorItem which is the base for GridViewItem and ListViewItem) and the IsEnabled property on the item being displayed.
public class CustomTemplateSelector : DataTemplateSelector
{
public DataTemplate ItemTemplate { get; set; }
protected override DataTemplate SelectTemplateCore(object item, DependencyObject container)
{
if(container is SelectorItem selector &&
item is SimpleItem si)
{
var myBinding = new Binding
{
Source = si,
Path = new PropertyPath(nameof(si.IsEnabled)),
Mode = BindingMode.TwoWay,
UpdateSourceTrigger = UpdateSourceTrigger.PropertyChanged
};
BindingOperations.SetBinding(selector, SelectorItem.IsEnabledProperty, myBinding);
}
return ItemTemplate;
}
}
In XAML we need to create an instance of the CustomTemplateSelector and set the ItemTemplate to be the layout for the item to be displayed.
And then, we apply the CustomTemplateSelector to the GridView.
Now items in the GridView can be disabled by adjusting the IsEnabled property on the item. For example, the following image shows Item 2 in the disabled state.
An alternative to using the existing Disabled state in the Template for the GridViewItem, is to set the IsHitTestEnabled property to false for the relevant GridViewItem. This effectively disables the item by preventing input on the disabled item from being processed by the GridView
This can be done in XAML by data binding the IsHitTestEnabled property on the root element of the Template for the GridViewItem to the IsEnabled property on the relevant item.
Note that because this option doesn’t use the Disabled state, you’ll need to update the layout for the item in the ItemTemplate to reflect that the item is disabled. For example, in the following XAML, a gray Border is displayed when the IsEnabled property is false (note using an inverted bool to visibility converter).
In this post, we’ve covered two ways to disable individual items in the GridView. The benefits of using the template selector approach are that it makes use of the existing Disabled visual state, and the template selector can be reused across any GridView or ListView.
A side note: If you plan to take this strategy cross-platform with Uno Platform, you’ll notice that the container parameter in the SelectTemplateCore method of the DataTemplateSelector isn’t a SelectItem. Instead, it’s a ContentPresenter, and you then need to access the TemplatedParent property to get the GridViewItem.
For those new to the Uno Platform, it allows for creating pixel-perfect, single-source C# and XAML apps that run natively on Windows, iOS, Android, macOS, Linux and Web via WebAssembly. In addition, it offers Figma integration for design-development handoff and a set of extensions to bootstrap your projects. Uno Platform is free, open-source (Apache 2.0), and available on GitHub.
The original version of this post was published on Nick Randolph’s blog. For additional Uno Platform and XAML articles by Nick, visit Nick’s .NET Travels.
To upgrade to the latest release of Uno Platform, please update your packages to 4.8 via your Visual Studio NuGet package manager! If you are new to Uno Platform, following our official getting started guide is the best way to get started. (5 min to complete)
Tags:
🕓 8 MIN Share on twitter Share …
🕓 3 MIN Share on twitter Share …
Uno Platform
360 rue Saint-Jacques, suite G101,
Montréal, Québec, Canada
H2Y 1P5
USA/CANADA toll free: +1-877-237-0471
International: +1-514-312-6958
Necessary cookies are absolutely essential for the website to function properly. This category only includes cookies that ensures basic functionalities and security features of the website. These cookies do not store any personal information.
Any cookies that may not be particularly necessary for the website to function and is used specifically to collect user personal data via analytics, ads, other embedded contents are termed as non-necessary cookies. It is mandatory to procure user consent prior to running these cookies on your website.
Uno Platform 5.2 LIVE Webinar – Today at 3 PM EST – Watch