Wizard with sidebar listbox question - disabling items?

Wizard for WPF Forum

Posted 9 years ago by Janene McCrillis - UI Software Engineer, Wireless Seismic
Avatar
I'm using the wizard withe the sidebar listbox. As the user goes through the steps I want to keep them from using the listbox to jump over a step, but I do want to allow them to click on previously completed steps to review their inputs so far.

How do I disable/enable individual items in the listbox?

Janene McCrillis
Wireless Seismic

Comments (2)

Posted 9 years ago by Actipro Software Support - Cleveland, OH, USA
Avatar
Hi Janene,

This is definitely possible, but requires a custom IValueConverter. What you'd do is add a Style for ListBoxItem, which disables them if their associated page is before the selected index. If you were to update the sidebar example from our Sample Browser, it would look like:
<ListBox Style="{StaticResource SidebarListBoxStyle}"
        ItemsSource="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=Items}"
        SelectedItem="{Binding RelativeSource={RelativeSource TemplatedParent}, Path=SelectedPage}">
    <ListBox.ItemContainerStyle>
        <Style TargetType="ListBoxItem">
            <Setter Property="IsEnabled">
                <Setter.Value>
                    <MultiBinding Converter="{x:Static sample:CustomValueConverter.Instance}">
                        <Binding />
                        <Binding Path="Wizard.SelectedPage" />
                    </MultiBinding>
                </Setter.Value>
            </Setter>
        </Style>
    </ListBox.ItemContainerStyle>
</ListBox>
The second binding above just ensures it's refreshed when the selected page changes. You could change this to "Wizard.SelectedIndex" also.

You would then need to add the CustomValueConverter to your application (and probably give it a better name). It's code looks like this:
public class CustomValueConverter : IMultiValueConverter {

    public readonly static CustomValueConverter Instance = new CustomValueConverter();

    public object Convert(object[] values, Type targetType, object parameter, CultureInfo culture) {
        if (values == null || values.Length < 1)
            throw new ArgumentException("values");

        WizardPage page = values[0] as WizardPage;
        if (page != null && page.Wizard != null) {
            int index = page.Wizard.Items.IndexOf(page);
            return (index <= page.Wizard.SelectedIndex);
        }

        return false;
    }

    public object[] ConvertBack(object value, Type[] targetTypes, object parameter, CultureInfo culture) {
        throw new NotImplementedException();
    }
}
This ensures that only the currently selected page and any previous page can be selected from the sidebar. But once you select a previous page, you cannot jump forward back to where you were. You could track the maximum selected index in an attached property and use that inplace of the "Wizard.SelectedPage" binding to allow jumping around to pages that have already been visited.


Actipro Software Support

Posted 9 years ago by Janene McCrillis - UI Software Engineer, Wireless Seismic
Avatar
Thanks!

Janene
The latest build of this product (v2019.1 build 0681) was released 1 month ago, which was after the last post in this thread.

Add Comment

Please log in to a validated account to post comments.