简体   繁体   中英

Can I disable the first item a WPF combobox within xaml code?

Consider the following combobox:

<ComboBox ItemsSource="{Binding Presets.VolumePresetList}" SelectedIndex="{Binding VolumePresetSelectedIndex, UpdateSourceTrigger=PropertyChanged}" Margin="10, 10" HorizontalAlignment="Left"
            MinWidth="150">
    <ComboBox.ItemTemplate>
        <DataTemplate>
            <TextBox Text="{Binding PresetName, UpdateSourceTrigger=Explicit}" VerticalAlignment="Center" Height="20" BorderThickness="0" LostFocus="TextBox_LostFocus" KeyUp="TextBox_KeyUp"/>
        </DataTemplate>
    </ComboBox.ItemTemplate>
</ComboBox>

The first Item of the combobox is a default preset with a corresponding default name in the textbox. The user therefore shouldn't be able to make input to this first item - thus I want to disable the textbox of the first item.

I know I could just run a function in the constructor of the containing class or the viewmodel, which disables the textbox on the first index, however I'm wondering if this is possible directly within the xaml code (which I would find a more elegant way of doing such static things).

You could make use of the fact that the PreviousData RelativeSource will return null for the first element of a collection. Knowing that you can add a DataTrigger to your DataTemplate to set the IsEnabled property of the TextBox to false.

Here is a simplified version of the ItemTemplate with a PreviousData binding:

       <ComboBox.ItemTemplate>
            <DataTemplate>
                <TextBox x:Name="TextBox" />
                <DataTemplate.Triggers>
                    <DataTrigger Binding="{Binding RelativeSource={RelativeSource Mode=PreviousData}}"
                                 Value="{x:Null}">
                        <Setter TargetName="TextBox" Property="IsEnabled" Value="False" />
                    </DataTrigger>
                </DataTemplate.Triggers>
            </DataTemplate>
        </ComboBox.ItemTemplate>

I have created a composite collection with DataBinding for ListView but the logic will be the same:

<ListView SelectedValue="{Binding youVMPropertyHere}">
    <ListView.ItemsSource>
        <CompositeCollection>
            <ListViewItem IsHitTestVisible="False">Default Item</ListViewItem>
            <CollectionContainer Collection="{Binding Source={StaticResource cvsPresetLists}}"/>
        </CompositeCollection>
    </ListView.ItemsSource>
<!-- Where-->
<Window.Resources>
    <CollectionViewSource Source="{Binding Presets.VolumePresetList}" x:Key="cvsPresetLists"/>
</Window.Resources>  

This way you can have the first item to be not selectable. I would also use SelectedValue instead of SelectedIndex .

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM